1e5c31af7Sopenharmony_ci#!/usr/bin/env python 2e5c31af7Sopenharmony_ci# -*- coding: utf-8 -*- 3e5c31af7Sopenharmony_ci 4e5c31af7Sopenharmony_ci#------------------------------------------------------------------------- 5e5c31af7Sopenharmony_ci# drawElements Quality Program utilities 6e5c31af7Sopenharmony_ci# -------------------------------------- 7e5c31af7Sopenharmony_ci# 8e5c31af7Sopenharmony_ci# Copyright 2015 The Android Open Source Project 9e5c31af7Sopenharmony_ci# 10e5c31af7Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 11e5c31af7Sopenharmony_ci# you may not use this file except in compliance with the License. 12e5c31af7Sopenharmony_ci# You may obtain a copy of the License at 13e5c31af7Sopenharmony_ci# 14e5c31af7Sopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 15e5c31af7Sopenharmony_ci# 16e5c31af7Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software 17e5c31af7Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 18e5c31af7Sopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19e5c31af7Sopenharmony_ci# See the License for the specific language governing permissions and 20e5c31af7Sopenharmony_ci# limitations under the License. 21e5c31af7Sopenharmony_ci# 22e5c31af7Sopenharmony_ci#------------------------------------------------------------------------- 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci# Check that the input file has no external include guards. 25e5c31af7Sopenharmony_ci# Returns with 0 exit code on success, 1 otherwise. 26e5c31af7Sopenharmony_ci 27e5c31af7Sopenharmony_ciimport re 28e5c31af7Sopenharmony_ciimport sys 29e5c31af7Sopenharmony_ciimport subprocess 30e5c31af7Sopenharmony_ci 31e5c31af7Sopenharmony_cidef git(*args, **kwargs): 32e5c31af7Sopenharmony_ci return subprocess.check_output(['git'] + list(args), **kwargs) 33e5c31af7Sopenharmony_ci 34e5c31af7Sopenharmony_cidef get_changed_paths(filter): 35e5c31af7Sopenharmony_ci output = git('diff', '--cached', '--name-only', '-z', '--diff-filter='+filter) 36e5c31af7Sopenharmony_ci return output.split('\0')[:-1] # remove trailing '' 37e5c31af7Sopenharmony_ci 38e5c31af7Sopenharmony_cidef get_against(): 39e5c31af7Sopenharmony_ci try: 40e5c31af7Sopenharmony_ci head = git('rev-parse', '--verify', 'HEAD', stderr=None) 41e5c31af7Sopenharmony_ci except subprocess.CalledProcessError: 42e5c31af7Sopenharmony_ci # Initial commit: diff against an empty tree object 43e5c31af7Sopenharmony_ci return '4b825dc642cb6eb9a060e54bf8d69288fbee4904' 44e5c31af7Sopenharmony_ci else: 45e5c31af7Sopenharmony_ci return 'HEAD' 46e5c31af7Sopenharmony_ci 47e5c31af7Sopenharmony_ciagainst = get_against() 48e5c31af7Sopenharmony_ci 49e5c31af7Sopenharmony_cisuccess = True 50e5c31af7Sopenharmony_ci 51e5c31af7Sopenharmony_cidef croak(path, line, msg, *args): 52e5c31af7Sopenharmony_ci global success 53e5c31af7Sopenharmony_ci success = False 54e5c31af7Sopenharmony_ci if path is not None: 55e5c31af7Sopenharmony_ci sys.stderr.write("%s:%d: " % (path, line or 0)) 56e5c31af7Sopenharmony_ci sys.stderr.write(msg % args if args else msg) 57e5c31af7Sopenharmony_ci if msg[-1] != '\n': 58e5c31af7Sopenharmony_ci sys.stderr.write('\n') 59e5c31af7Sopenharmony_ci 60e5c31af7Sopenharmony_cidef check_filenames(): 61e5c31af7Sopenharmony_ci try: 62e5c31af7Sopenharmony_ci allownonascii = git('config', '--get', '--bool', 'hooks.allownonascii') 63e5c31af7Sopenharmony_ci except subprocess.CalledProcessError: 64e5c31af7Sopenharmony_ci pass 65e5c31af7Sopenharmony_ci else: 66e5c31af7Sopenharmony_ci if allownonascii == 'true': 67e5c31af7Sopenharmony_ci return 68e5c31af7Sopenharmony_ci 69e5c31af7Sopenharmony_ci for path in get_changed_paths('ACR'): 70e5c31af7Sopenharmony_ci try: 71e5c31af7Sopenharmony_ci path.decode('ascii') 72e5c31af7Sopenharmony_ci except UnicodeDecodeError: 73e5c31af7Sopenharmony_ci croak(path, 0, "Non-ASCII file name") 74e5c31af7Sopenharmony_ci 75e5c31af7Sopenharmony_cidef check_whitespace(): 76e5c31af7Sopenharmony_ci try: 77e5c31af7Sopenharmony_ci git('diff-index', '--check', '--cached', against, stderr=None) 78e5c31af7Sopenharmony_ci except subprocess.CalledProcessError as e: 79e5c31af7Sopenharmony_ci sys.stderr.write(e.output) 80e5c31af7Sopenharmony_ci global success 81e5c31af7Sopenharmony_ci success = False 82e5c31af7Sopenharmony_ci 83e5c31af7Sopenharmony_ciguard_re = re.compile('^[ \t]*#\s*ifndef\s+_.*?_H(PP)?\n' 84e5c31af7Sopenharmony_ci '\s*#\s*include\s+(".*?")\s*\n' 85e5c31af7Sopenharmony_ci '\s*#\s*endif.*?$', 86e5c31af7Sopenharmony_ci re.MULTILINE) 87e5c31af7Sopenharmony_ci 88e5c31af7Sopenharmony_cidef check_external_guards (infile): 89e5c31af7Sopenharmony_ci contents = infile.read() 90e5c31af7Sopenharmony_ci for m in guard_re.finditer(contents): 91e5c31af7Sopenharmony_ci lineno = 1 + contents[:m.start()].count('\n') 92e5c31af7Sopenharmony_ci croak(infile.name, lineno, "External include guard") 93e5c31af7Sopenharmony_ci croak(None, None, m.group(0)) 94e5c31af7Sopenharmony_ci 95e5c31af7Sopenharmony_cidef check_changed_files(): 96e5c31af7Sopenharmony_ci for path in get_changed_paths('AM'): 97e5c31af7Sopenharmony_ci check_external_guards(open(path)) 98e5c31af7Sopenharmony_ci 99e5c31af7Sopenharmony_cidef main(): 100e5c31af7Sopenharmony_ci check_filenames() 101e5c31af7Sopenharmony_ci check_changed_files() 102e5c31af7Sopenharmony_ci check_whitespace() 103e5c31af7Sopenharmony_ci if not success: 104e5c31af7Sopenharmony_ci exit(1) 105e5c31af7Sopenharmony_ci 106e5c31af7Sopenharmony_ciif __name__ == '__main__': 107e5c31af7Sopenharmony_ci main() 108