michael@0: #!/usr/bin/env python michael@0: # Copyright (c) 2012 The LibYuv Project Authors. All rights reserved. michael@0: # michael@0: # Use of this source code is governed by a BSD-style license michael@0: # that can be found in the LICENSE file in the root of the source michael@0: # tree. An additional intellectual property rights grant can be found michael@0: # in the file PATENTS. All contributing project authors may michael@0: # be found in the AUTHORS file in the root of the source tree. michael@0: michael@0: """ michael@0: Copied from Chrome's src/tools/valgrind/memcheck/PRESUBMIT.py michael@0: michael@0: See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts michael@0: for more details on the presubmit API built into gcl. michael@0: """ michael@0: michael@0: import os michael@0: import re michael@0: import sys michael@0: michael@0: def CheckChange(input_api, output_api): michael@0: """Checks the memcheck suppressions files for bad data.""" michael@0: michael@0: # Add the path to the Chrome valgrind dir to the import path: michael@0: tools_vg_path = os.path.join(input_api.PresubmitLocalPath(), '..', '..', michael@0: 'valgrind') michael@0: sys.path.append(tools_vg_path) michael@0: import suppressions michael@0: michael@0: sup_regex = re.compile('suppressions.*\.txt$') michael@0: suppressions = {} michael@0: errors = [] michael@0: check_for_memcheck = False michael@0: # skip_next_line has 3 possible values: michael@0: # - False: don't skip the next line. michael@0: # - 'skip_suppression_name': the next line is a suppression name, skip. michael@0: # - 'skip_param': the next line is a system call parameter error, skip. michael@0: skip_next_line = False michael@0: for f in filter(lambda x: sup_regex.search(x.LocalPath()), michael@0: input_api.AffectedFiles()): michael@0: for line, line_num in zip(f.NewContents(), michael@0: xrange(1, len(f.NewContents()) + 1)): michael@0: line = line.lstrip() michael@0: if line.startswith('#') or not line: michael@0: continue michael@0: michael@0: if skip_next_line: michael@0: if skip_next_line == 'skip_suppression_name': michael@0: if 'insert_a_suppression_name_here' in line: michael@0: errors.append('"insert_a_suppression_name_here" is not a valid ' michael@0: 'suppression name') michael@0: if suppressions.has_key(line): michael@0: if f.LocalPath() == suppressions[line][1]: michael@0: errors.append('suppression with name "%s" at %s line %s ' michael@0: 'has already been defined at line %s' % michael@0: (line, f.LocalPath(), line_num, michael@0: suppressions[line][1])) michael@0: else: michael@0: errors.append('suppression with name "%s" at %s line %s ' michael@0: 'has already been defined at %s line %s' % michael@0: (line, f.LocalPath(), line_num, michael@0: suppressions[line][0], suppressions[line][1])) michael@0: else: michael@0: suppressions[line] = (f, line_num) michael@0: check_for_memcheck = True; michael@0: skip_next_line = False michael@0: continue michael@0: if check_for_memcheck: michael@0: if not line.startswith('Memcheck:'): michael@0: errors.append('"%s" should be "Memcheck:..." in %s line %s' % michael@0: (line, f.LocalPath(), line_num)) michael@0: check_for_memcheck = False; michael@0: if line == '{': michael@0: skip_next_line = 'skip_suppression_name' michael@0: continue michael@0: if line == "Memcheck:Param": michael@0: skip_next_line = 'skip_param' michael@0: continue michael@0: michael@0: if (line.startswith('fun:') or line.startswith('obj:') or michael@0: line.startswith('Memcheck:') or line == '}' or michael@0: line == '...'): michael@0: continue michael@0: errors.append('"%s" is probably wrong: %s line %s' % (line, f.LocalPath(), michael@0: line_num)) michael@0: if errors: michael@0: return [output_api.PresubmitError('\n'.join(errors))] michael@0: return [] michael@0: michael@0: def CheckChangeOnUpload(input_api, output_api): michael@0: return CheckChange(input_api, output_api) michael@0: michael@0: def CheckChangeOnCommit(input_api, output_api): michael@0: return CheckChange(input_api, output_api) michael@0: michael@0: def GetPreferredTrySlaves(): michael@0: # We don't have any memcheck slaves yet, so there's no use for this method. michael@0: # When we have, the slave name(s) should be put into this list. michael@0: return []