• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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