#!/usr/bin/env python3 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file # for details. All rights reserved. Use of this source code is governed by a # BSD-style license that can be found in the LICENSE file. import os import cpplint import re USE_PYTHON3 = True # memcpy does not handle overlapping memory regions. Even though this # is well documented it seems to be used in error quite often. To avoid # problems we disallow the direct use of memcpy. The exceptions are in # third-party code and in platform/globals.h which uses it to implement # bit_cast and bit_copy. def CheckMemcpy(filename): if filename.endswith(os.path.join('platform', 'globals.h')) or \ filename.find('third_party') != -1: return 0 fh = open(filename, 'r') content = fh.read() match = re.search('\\bmemcpy\\b', content) if match: offset = match.start() end_of_line = content.index('\n', offset) # We allow explicit use of memcpy with an opt-in via NOLINT if 'NOLINT' not in content[offset:end_of_line]: line_number = content[0:match.start()].count('\n') + 1 print("%s:%d: use of memcpy is forbidden" % (filename, line_number)) return 1 return 0 def RunLint(input_api, output_api): result = [] cpplint._cpplint_state.ResetErrorCounts() memcpy_match_count = 0 # Find all .cc and .h files in the change list. for git_file in input_api.AffectedTextFiles(): filename = git_file.AbsoluteLocalPath() if filename.endswith('.cc') or ( # cpplint complains about the style of #ifndefs in our .pbzero.h # files, but they are generated by the protozero compiler, so we # can't fix this. not filename.endswith('.pbzero.h') and filename.endswith('.h')): # Run cpplint on the file. cpplint.ProcessFile(filename, 1) # Check for memcpy use. memcpy_match_count += CheckMemcpy(filename) # Report a presubmit error if any of the files had an error. if cpplint._cpplint_state.error_count > 0 or memcpy_match_count > 0: result = [output_api.PresubmitError('Failed cpplint check.')] return result def CheckGn(input_api, output_api): return input_api.canned_checks.CheckGNFormatted(input_api, output_api) def CheckFormatted(input_api, output_api): def convert_warning_to_error(presubmit_result): if not presubmit_result.fatal: # Convert this warning to an error. result_json = presubmit_result.json_format() return output_api.PresubmitError( message=result_json['message'], items=result_json['items'], long_text=result_json['long_text']) return presubmit_result results = input_api.canned_checks.CheckPatchFormatted(input_api, output_api) return [convert_warning_to_error(r) for r in results] def CheckChangeOnUpload(input_api, output_api): return (RunLint(input_api, output_api) + CheckGn(input_api, output_api) + CheckFormatted(input_api, output_api)) def CheckChangeOnCommit(input_api, output_api): return (RunLint(input_api, output_api) + CheckGn(input_api, output_api) + CheckFormatted(input_api, output_api))