blob: 25a577b010854836d261058eff49f359d78f7e94 [file] [log] [blame]
#!/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))