1 # Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 # Use of this source code is governed by a BSD-style license that can be 3 # found in the LICENSE file. 4 5 """ 6 See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts 7 for more details on the presubmit API built into gcl. 8 """ 9 10 import re 11 12 def CheckChange(input_api, output_api): 13 """Checks the memcheck suppressions files for bad data.""" 14 sup_regex = re.compile('suppressions.*\.txt$') 15 suppressions = {} 16 errors = [] 17 check_for_memcheck = False 18 # skip_next_line has 3 possible values: 19 # - False: don't skip the next line. 20 # - 'skip_suppression_name': the next line is a suppression name, skip. 21 # - 'skip_param': the next line is a system call parameter error, skip. 22 skip_next_line = False 23 for f in filter(lambda x: sup_regex.search(x.LocalPath()), 24 input_api.AffectedFiles()): 25 for line, line_num in zip(f.NewContents(), 26 xrange(1, len(f.NewContents()) + 1)): 27 line = line.lstrip() 28 if line.startswith('#') or not line: 29 continue 30 31 if skip_next_line: 32 if skip_next_line == 'skip_suppression_name': 33 if 'insert_a_suppression_name_here' in line: 34 errors.append('"insert_a_suppression_name_here" is not a valid ' 35 'suppression name') 36 if suppressions.has_key(line): 37 if f.LocalPath() == suppressions[line][1]: 38 errors.append('suppression with name "%s" at %s line %s ' 39 'has already been defined at line %s' % 40 (line, f.LocalPath(), line_num, 41 suppressions[line][1])) 42 else: 43 errors.append('suppression with name "%s" at %s line %s ' 44 'has already been defined at %s line %s' % 45 (line, f.LocalPath(), line_num, 46 suppressions[line][0], suppressions[line][1])) 47 else: 48 suppressions[line] = (f, line_num) 49 check_for_memcheck = True; 50 skip_next_line = False 51 continue 52 if check_for_memcheck: 53 if not line.startswith('Memcheck:'): 54 errors.append('"%s" should be "Memcheck:..." in %s line %s' % 55 (line, f.LocalPath(), line_num)) 56 check_for_memcheck = False; 57 if line == '{': 58 skip_next_line = 'skip_suppression_name' 59 continue 60 if line == "Memcheck:Param": 61 skip_next_line = 'skip_param' 62 continue 63 64 if (line.startswith('fun:') or line.startswith('obj:') or 65 line.startswith('Memcheck:') or line == '}' or 66 line == '...'): 67 continue 68 errors.append('"%s" is probably wrong: %s line %s' % (line, f.LocalPath(), 69 line_num)) 70 if errors: 71 return [output_api.PresubmitError('\n'.join(errors))] 72 return [] 73 74 def CheckChangeOnUpload(input_api, output_api): 75 return CheckChange(input_api, output_api) 76 77 def CheckChangeOnCommit(input_api, output_api): 78 return CheckChange(input_api, output_api) 79 80 def GetPreferredTrySlaves(): 81 return ['linux_valgrind', 'mac_valgrind'] 82