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