|  | #!/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)) |