1#!/usr/bin/env python 2# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3# 4# Use of this source code is governed by a BSD-style license 5# that can be found in the LICENSE file in the root of the source 6# tree. An additional intellectual property rights grant can be found 7# in the file PATENTS. All contributing project authors may 8# be found in the AUTHORS file in the root of the source tree. 9 10""" 11Copied from Chrome's src/tools/valgrind/memcheck/PRESUBMIT.py 12 13See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts 14for more details on the presubmit API built into gcl. 15""" 16 17import os 18import re 19import sys 20 21def CheckChange(input_api, output_api): 22 """Checks the memcheck suppressions files for bad data.""" 23 24 # Add the path to the Chrome valgrind dir to the import path: 25 tools_vg_path = os.path.join(input_api.PresubmitLocalPath(), '..', '..', 26 'valgrind') 27 sys.path.append(tools_vg_path) 28 import suppressions 29 30 sup_regex = re.compile('suppressions.*\.txt$') 31 suppressions = {} 32 errors = [] 33 check_for_memcheck = False 34 # skip_next_line has 3 possible values: 35 # - False: don't skip the next line. 36 # - 'skip_suppression_name': the next line is a suppression name, skip. 37 # - 'skip_param': the next line is a system call parameter error, skip. 38 skip_next_line = False 39 for f in filter(lambda x: sup_regex.search(x.LocalPath()), 40 input_api.AffectedFiles()): 41 for line, line_num in zip(f.NewContents(), 42 xrange(1, len(f.NewContents()) + 1)): 43 line = line.lstrip() 44 if line.startswith('#') or not line: 45 continue 46 47 if skip_next_line: 48 if skip_next_line == 'skip_suppression_name': 49 if 'insert_a_suppression_name_here' in line: 50 errors.append('"insert_a_suppression_name_here" is not a valid ' 51 'suppression name') 52 if suppressions.has_key(line): 53 if f.LocalPath() == suppressions[line][1]: 54 errors.append('suppression with name "%s" at %s line %s ' 55 'has already been defined at line %s' % 56 (line, f.LocalPath(), line_num, 57 suppressions[line][1])) 58 else: 59 errors.append('suppression with name "%s" at %s line %s ' 60 'has already been defined at %s line %s' % 61 (line, f.LocalPath(), line_num, 62 suppressions[line][0], suppressions[line][1])) 63 else: 64 suppressions[line] = (f, line_num) 65 check_for_memcheck = True; 66 skip_next_line = False 67 continue 68 if check_for_memcheck: 69 if not line.startswith('Memcheck:'): 70 errors.append('"%s" should be "Memcheck:..." in %s line %s' % 71 (line, f.LocalPath(), line_num)) 72 check_for_memcheck = False; 73 if line == '{': 74 skip_next_line = 'skip_suppression_name' 75 continue 76 if line == "Memcheck:Param": 77 skip_next_line = 'skip_param' 78 continue 79 80 if (line.startswith('fun:') or line.startswith('obj:') or 81 line.startswith('Memcheck:') or line == '}' or 82 line == '...'): 83 continue 84 errors.append('"%s" is probably wrong: %s line %s' % (line, f.LocalPath(), 85 line_num)) 86 if errors: 87 return [output_api.PresubmitError('\n'.join(errors))] 88 return [] 89 90 91def CheckChangeOnUpload(input_api, output_api): 92 return CheckChange(input_api, output_api) 93 94 95def CheckChangeOnCommit(input_api, output_api): 96 return CheckChange(input_api, output_api) 97 98 99def GetPreferredTrySlaves(): 100 return ['linux_memcheck'] 101