verifiers.py (11510:b539c1a6e597) | verifiers.py (11541:3d518944f0cc) |
---|---|
1#!/usr/bin/env python 2# 3# Copyright (c) 2014, 2016 ARM Limited 4# All rights reserved 5# 6# The license below extends only to copyright in the software and shall 7# not be construed as granting a license to any other intellectual 8# property including but not limited to intellectual property relating --- 171 unchanged lines hidden (view full) --- 180 (like SortedIncludes) must override this entire function. 181 """ 182 pass 183 184class LineVerifier(Verifier): 185 def check(self, filename, regions=all_regions): 186 f = self.open(filename, 'r') 187 | 1#!/usr/bin/env python 2# 3# Copyright (c) 2014, 2016 ARM Limited 4# All rights reserved 5# 6# The license below extends only to copyright in the software and shall 7# not be construed as granting a license to any other intellectual 8# property including but not limited to intellectual property relating --- 171 unchanged lines hidden (view full) --- 180 (like SortedIncludes) must override this entire function. 181 """ 182 pass 183 184class LineVerifier(Verifier): 185 def check(self, filename, regions=all_regions): 186 f = self.open(filename, 'r') 187 |
188 lang = lang_type(filename) 189 assert lang in self.languages 190 |
|
188 errors = 0 189 for num,line in enumerate(f): 190 if num not in regions: 191 continue 192 line = line.rstrip('\n') | 191 errors = 0 192 for num,line in enumerate(f): 193 if num not in regions: 194 continue 195 line = line.rstrip('\n') |
193 if not self.check_line(line): | 196 if not self.check_line(line, language=lang): |
194 self.ui.write("invalid %s in %s:%d\n" % \ 195 (self.test_name, filename, num + 1)) 196 if self.ui.verbose: 197 self.ui.write(">>%s<<\n" % line[:-1]) 198 errors += 1 | 197 self.ui.write("invalid %s in %s:%d\n" % \ 198 (self.test_name, filename, num + 1)) 199 if self.ui.verbose: 200 self.ui.write(">>%s<<\n" % line[:-1]) 201 errors += 1 |
202 f.close() |
|
199 return errors 200 201 def fix(self, filename, regions=all_regions): 202 f = self.open(filename, 'r+') 203 | 203 return errors 204 205 def fix(self, filename, regions=all_regions): 206 f = self.open(filename, 'r+') 207 |
208 lang = lang_type(filename) 209 assert lang in self.languages 210 |
|
204 lines = list(f) 205 206 f.seek(0) 207 f.truncate() 208 209 for i,line in enumerate(lines): 210 line = line.rstrip('\n') 211 if i in regions: | 211 lines = list(f) 212 213 f.seek(0) 214 f.truncate() 215 216 for i,line in enumerate(lines): 217 line = line.rstrip('\n') 218 if i in regions: |
212 line = self.fix_line(line) | 219 line = self.fix_line(line, language=lang) |
213 214 f.write(line) 215 f.write("\n") 216 f.close() | 220 221 f.write(line) 222 f.write("\n") 223 f.close() |
224 self.current_language = None |
|
217 | 225 |
218 | |
219 @abstractmethod | 226 @abstractmethod |
220 def check_line(self, line): | 227 def check_line(self, line, **kwargs): |
221 pass 222 223 @abstractmethod | 228 pass 229 230 @abstractmethod |
224 def fix_line(self, line): | 231 def fix_line(self, line, **kwargs): |
225 pass 226 227class Whitespace(LineVerifier): 228 """Check whitespace. 229 230 Specifically: 231 - No tabs used for indent 232 - No trailing whitespace 233 """ 234 | 232 pass 233 234class Whitespace(LineVerifier): 235 """Check whitespace. 236 237 Specifically: 238 - No tabs used for indent 239 - No trailing whitespace 240 """ 241 |
235 languages = set(('C', 'C++', 'swig', 'python', 'asm', 'isa', 'scons')) | 242 languages = set(('C', 'C++', 'swig', 'python', 'asm', 'isa', 'scons', 243 'make', 'dts')) 244 trail_only = set(('make', 'dts')) 245 |
236 test_name = 'whitespace' 237 opt_name = 'white' 238 239 _lead = re.compile(r'^([ \t]+)') 240 _trail = re.compile(r'([ \t]+)$') 241 | 246 test_name = 'whitespace' 247 opt_name = 'white' 248 249 _lead = re.compile(r'^([ \t]+)') 250 _trail = re.compile(r'([ \t]+)$') 251 |
242 def check_line(self, line): 243 match = Whitespace._lead.search(line) 244 if match and match.group(1).find('\t') != -1: 245 return False | |
246 | 252 |
253 def skip_lead(self, language): 254 return language in Whitespace.trail_only 255 256 def check_line(self, line, language): 257 if not self.skip_lead(language): 258 match = Whitespace._lead.search(line) 259 if match and match.group(1).find('\t') != -1: 260 return False 261 |
|
247 match = Whitespace._trail.search(line) 248 if match: 249 return False 250 251 return True 252 | 262 match = Whitespace._trail.search(line) 263 if match: 264 return False 265 266 return True 267 |
253 def fix_line(self, line): 254 if Whitespace._lead.search(line): | 268 def fix_line(self, line, language): 269 if not self.skip_lead(language) and Whitespace._lead.search(line): |
255 newline = '' 256 for i,c in enumerate(line): 257 if c == ' ': 258 newline += ' ' 259 elif c == '\t': 260 newline += ' ' * (tabsize - len(newline) % tabsize) 261 else: 262 newline += line[i:] --- 61 unchanged lines hidden (view full) --- 324 """Check for exactly one space after if/while/for""" 325 326 languages = set(('C', 'C++')) 327 test_name = 'spacing after if/while/for' 328 opt_name = 'control' 329 330 _any_control = re.compile(r'\b(if|while|for)([ \t]*)\(') 331 | 270 newline = '' 271 for i,c in enumerate(line): 272 if c == ' ': 273 newline += ' ' 274 elif c == '\t': 275 newline += ' ' * (tabsize - len(newline) % tabsize) 276 else: 277 newline += line[i:] --- 61 unchanged lines hidden (view full) --- 339 """Check for exactly one space after if/while/for""" 340 341 languages = set(('C', 'C++')) 342 test_name = 'spacing after if/while/for' 343 opt_name = 'control' 344 345 _any_control = re.compile(r'\b(if|while|for)([ \t]*)\(') 346 |
332 def check_line(self, line): | 347 def check_line(self, line, **kwargs): |
333 match = ControlSpace._any_control.search(line) 334 return not (match and match.group(2) != " ") 335 | 348 match = ControlSpace._any_control.search(line) 349 return not (match and match.group(2) != " ") 350 |
336 def fix_line(self, line): | 351 def fix_line(self, line, **kwargs): |
337 new_line = _any_control.sub(r'\1 (', line) 338 return new_line 339 340 341class LineLength(LineVerifier): 342 languages = set(('C', 'C++', 'swig', 'python', 'asm', 'isa', 'scons')) 343 test_name = 'line length' 344 opt_name = 'length' 345 | 352 new_line = _any_control.sub(r'\1 (', line) 353 return new_line 354 355 356class LineLength(LineVerifier): 357 languages = set(('C', 'C++', 'swig', 'python', 'asm', 'isa', 'scons')) 358 test_name = 'line length' 359 opt_name = 'length' 360 |
346 def check_line(self, line): | 361 def check_line(self, line, **kwargs): |
347 return style.normalized_len(line) <= 79 348 | 362 return style.normalized_len(line) <= 79 363 |
349 def fix(self, filename, regions=all_regions): | 364 def fix(self, filename, regions=all_regions, **kwargs): |
350 self.ui.write("Warning: cannot automatically fix overly long lines.\n") 351 352 def fix_line(self, line): 353 pass 354 355class ControlCharacters(LineVerifier): 356 languages = set(('C', 'C++', 'swig', 'python', 'asm', 'isa', 'scons')) 357 test_name = 'control character' 358 opt_name = 'ascii' 359 360 valid = ('\n', '\t') 361 invalid = "".join([chr(i) for i in range(0, 0x20) if chr(i) not in valid]) 362 | 365 self.ui.write("Warning: cannot automatically fix overly long lines.\n") 366 367 def fix_line(self, line): 368 pass 369 370class ControlCharacters(LineVerifier): 371 languages = set(('C', 'C++', 'swig', 'python', 'asm', 'isa', 'scons')) 372 test_name = 'control character' 373 opt_name = 'ascii' 374 375 valid = ('\n', '\t') 376 invalid = "".join([chr(i) for i in range(0, 0x20) if chr(i) not in valid]) 377 |
363 def check_line(self, line): | 378 def check_line(self, line, **kwargs): |
364 return self.fix_line(line) == line 365 | 379 return self.fix_line(line) == line 380 |
366 def fix_line(self, line): | 381 def fix_line(self, line, **kwargs): |
367 return line.translate(None, ControlCharacters.invalid) 368 369class BoolCompare(LineVerifier): 370 languages = set(('C', 'C++', 'python')) 371 test_name = 'boolean comparison' 372 opt_name = 'boolcomp' 373 374 regex = re.compile(r'\s*==\s*([Tt]rue|[Ff]alse)\b') 375 | 382 return line.translate(None, ControlCharacters.invalid) 383 384class BoolCompare(LineVerifier): 385 languages = set(('C', 'C++', 'python')) 386 test_name = 'boolean comparison' 387 opt_name = 'boolcomp' 388 389 regex = re.compile(r'\s*==\s*([Tt]rue|[Ff]alse)\b') 390 |
376 def check_line(self, line): | 391 def check_line(self, line, **kwargs): |
377 return self.regex.search(line) == None 378 | 392 return self.regex.search(line) == None 393 |
379 def fix_line(self, line): | 394 def fix_line(self, line, **kwargs): |
380 match = self.regex.search(line) 381 if match: 382 if match.group(1) in ('true', 'True'): 383 line = self.regex.sub('', line) 384 else: 385 self.ui.write("Warning: cannot automatically fix " 386 "comparisons with false/False.\n") 387 return line 388 389def is_verifier(cls): 390 """Determine if a class is a Verifier that can be instantiated""" 391 392 return inspect.isclass(cls) and issubclass(cls, Verifier) and \ 393 not inspect.isabstract(cls) 394 395# list of all verifier classes 396all_verifiers = [ v for n, v in \ 397 inspect.getmembers(sys.modules[__name__], is_verifier) ] | 395 match = self.regex.search(line) 396 if match: 397 if match.group(1) in ('true', 'True'): 398 line = self.regex.sub('', line) 399 else: 400 self.ui.write("Warning: cannot automatically fix " 401 "comparisons with false/False.\n") 402 return line 403 404def is_verifier(cls): 405 """Determine if a class is a Verifier that can be instantiated""" 406 407 return inspect.isclass(cls) and issubclass(cls, Verifier) and \ 408 not inspect.isabstract(cls) 409 410# list of all verifier classes 411all_verifiers = [ v for n, v in \ 412 inspect.getmembers(sys.modules[__name__], is_verifier) ] |