Home | History | Annotate | Download | only in memcheck
      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