1e5c31af7Sopenharmony_ci# -*- coding: utf-8 -*-
2e5c31af7Sopenharmony_ci
3e5c31af7Sopenharmony_ci#-------------------------------------------------------------------------
4e5c31af7Sopenharmony_ci# drawElements Quality Program utilities
5e5c31af7Sopenharmony_ci# --------------------------------------
6e5c31af7Sopenharmony_ci#
7e5c31af7Sopenharmony_ci# Copyright 2015 The Android Open Source Project
8e5c31af7Sopenharmony_ci#
9e5c31af7Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
10e5c31af7Sopenharmony_ci# you may not use this file except in compliance with the License.
11e5c31af7Sopenharmony_ci# You may obtain a copy of the License at
12e5c31af7Sopenharmony_ci#
13e5c31af7Sopenharmony_ci#      http://www.apache.org/licenses/LICENSE-2.0
14e5c31af7Sopenharmony_ci#
15e5c31af7Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software
16e5c31af7Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
17e5c31af7Sopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18e5c31af7Sopenharmony_ci# See the License for the specific language governing permissions and
19e5c31af7Sopenharmony_ci# limitations under the License.
20e5c31af7Sopenharmony_ci#
21e5c31af7Sopenharmony_ci#-------------------------------------------------------------------------
22e5c31af7Sopenharmony_ci
23e5c31af7Sopenharmony_ciimport os
24e5c31af7Sopenharmony_ciimport sys
25e5c31af7Sopenharmony_cifrom fnmatch import fnmatch
26e5c31af7Sopenharmony_cifrom optparse import OptionParser
27e5c31af7Sopenharmony_ci
28e5c31af7Sopenharmony_ciHEADER_PATTERNS		= ["*.hpp", "*.h"]
29e5c31af7Sopenharmony_ciIGNORE_FILES		= set(["tcuEAGLView.h", "tcuIOSAppDelegate.h", "tcuIOSViewController.h"])
30e5c31af7Sopenharmony_ciCHECK_END_COMMENT	= True
31e5c31af7Sopenharmony_ci
32e5c31af7Sopenharmony_cidef getIncludeGuardName (headerFile):
33e5c31af7Sopenharmony_ci	return '_' + os.path.basename(headerFile).upper().replace('.', '_')
34e5c31af7Sopenharmony_ci
35e5c31af7Sopenharmony_cidef hasValidIncludeGuard (headerFile):
36e5c31af7Sopenharmony_ci	includeGuard	= getIncludeGuardName(headerFile)
37e5c31af7Sopenharmony_ci	f				= open(headerFile, 'rt')
38e5c31af7Sopenharmony_ci	isHpp			= headerFile[-4:] == ".hpp"
39e5c31af7Sopenharmony_ci
40e5c31af7Sopenharmony_ci	line0 = f.readline().strip()
41e5c31af7Sopenharmony_ci	line1 = f.readline().strip()
42e5c31af7Sopenharmony_ci
43e5c31af7Sopenharmony_ci	if line0 != ("#ifndef %s" % includeGuard):
44e5c31af7Sopenharmony_ci		return False
45e5c31af7Sopenharmony_ci	if line1 != ("#define %s" % includeGuard):
46e5c31af7Sopenharmony_ci		return False
47e5c31af7Sopenharmony_ci
48e5c31af7Sopenharmony_ci	if CHECK_END_COMMENT:
49e5c31af7Sopenharmony_ci		lastLine		= ""
50e5c31af7Sopenharmony_ci		expectedComment	= ("#endif // %s" if isHpp else "#endif /* %s */") % includeGuard
51e5c31af7Sopenharmony_ci		for line in f:
52e5c31af7Sopenharmony_ci			lastLine = line.strip()
53e5c31af7Sopenharmony_ci
54e5c31af7Sopenharmony_ci		if lastLine != expectedComment:
55e5c31af7Sopenharmony_ci#			print("'%s' != '%s'" % (lastLine, expectedComment))
56e5c31af7Sopenharmony_ci			return False
57e5c31af7Sopenharmony_ci
58e5c31af7Sopenharmony_ci	f.close()
59e5c31af7Sopenharmony_ci	return True
60e5c31af7Sopenharmony_ci
61e5c31af7Sopenharmony_cidef fixIncludeGuard (headerFile):
62e5c31af7Sopenharmony_ci	f				= open(headerFile, 'rt')
63e5c31af7Sopenharmony_ci	lines			= []
64e5c31af7Sopenharmony_ci	isHpp			= headerFile[-4:] == ".hpp"
65e5c31af7Sopenharmony_ci	includeGuard	=  getIncludeGuardName(headerFile)
66e5c31af7Sopenharmony_ci
67e5c31af7Sopenharmony_ci	for line in f:
68e5c31af7Sopenharmony_ci		lines.append(line)
69e5c31af7Sopenharmony_ci	f.close()
70e5c31af7Sopenharmony_ci
71e5c31af7Sopenharmony_ci	# Replace include guards
72e5c31af7Sopenharmony_ci	lines[0] = "#ifndef %s\n" % includeGuard
73e5c31af7Sopenharmony_ci	lines[1] = "#define %s\n" % includeGuard
74e5c31af7Sopenharmony_ci
75e5c31af7Sopenharmony_ci	if CHECK_END_COMMENT:
76e5c31af7Sopenharmony_ci		lines[len(lines)-1] = ("#endif // %s\n" if isHpp else "#endif /* %s */\n") % includeGuard
77e5c31af7Sopenharmony_ci
78e5c31af7Sopenharmony_ci	f = open(headerFile, 'wt')
79e5c31af7Sopenharmony_ci	for line in lines:
80e5c31af7Sopenharmony_ci		f.write(line)
81e5c31af7Sopenharmony_ci	f.close()
82e5c31af7Sopenharmony_ci
83e5c31af7Sopenharmony_cidef isHeader (filename):
84e5c31af7Sopenharmony_ci	if os.path.basename(filename) in IGNORE_FILES:
85e5c31af7Sopenharmony_ci		return False
86e5c31af7Sopenharmony_ci
87e5c31af7Sopenharmony_ci	for pattern in HEADER_PATTERNS:
88e5c31af7Sopenharmony_ci		if fnmatch(filename, pattern):
89e5c31af7Sopenharmony_ci			return True
90e5c31af7Sopenharmony_ci	return False
91e5c31af7Sopenharmony_ci
92e5c31af7Sopenharmony_cidef getHeaderFileList (path):
93e5c31af7Sopenharmony_ci	headers = []
94e5c31af7Sopenharmony_ci	if os.path.isfile(path):
95e5c31af7Sopenharmony_ci		if isHeader(path):
96e5c31af7Sopenharmony_ci			headers.append(path)
97e5c31af7Sopenharmony_ci	else:
98e5c31af7Sopenharmony_ci		for root, dirs, files in os.walk(path):
99e5c31af7Sopenharmony_ci			for file in files:
100e5c31af7Sopenharmony_ci				if isHeader(file):
101e5c31af7Sopenharmony_ci					headers.append(os.path.join(root, file))
102e5c31af7Sopenharmony_ci	return headers
103e5c31af7Sopenharmony_ci
104e5c31af7Sopenharmony_cidef checkIncludeGuards (files):
105e5c31af7Sopenharmony_ci    error = False
106e5c31af7Sopenharmony_ci    for file in files:
107e5c31af7Sopenharmony_ci        if isHeader(file):
108e5c31af7Sopenharmony_ci            if not hasValidIncludeGuard(file):
109e5c31af7Sopenharmony_ci                error = True
110e5c31af7Sopenharmony_ci                print("File %s contains invalid include guards" % file)
111e5c31af7Sopenharmony_ci    return not error
112e5c31af7Sopenharmony_ci
113e5c31af7Sopenharmony_ciif __name__ == "__main__":
114e5c31af7Sopenharmony_ci	parser = OptionParser()
115e5c31af7Sopenharmony_ci	parser.add_option("-x", "--fix", action="store_true", dest="fix", default=False, help="attempt to fix include guards (use with caution)")
116e5c31af7Sopenharmony_ci
117e5c31af7Sopenharmony_ci	(options, args)	= parser.parse_args()
118e5c31af7Sopenharmony_ci	fix				= options.fix
119e5c31af7Sopenharmony_ci	headers			= []
120e5c31af7Sopenharmony_ci	invalidHeaders	= []
121e5c31af7Sopenharmony_ci
122e5c31af7Sopenharmony_ci	for dir in args:
123e5c31af7Sopenharmony_ci		headers += getHeaderFileList(os.path.normpath(dir))
124e5c31af7Sopenharmony_ci
125e5c31af7Sopenharmony_ci	print("Checking...")
126e5c31af7Sopenharmony_ci	for header in headers:
127e5c31af7Sopenharmony_ci		print("  %s" % header)
128e5c31af7Sopenharmony_ci		if not hasValidIncludeGuard(header):
129e5c31af7Sopenharmony_ci			invalidHeaders.append(header)
130e5c31af7Sopenharmony_ci
131e5c31af7Sopenharmony_ci	print("")
132e5c31af7Sopenharmony_ci	if len(invalidHeaders) > 0:
133e5c31af7Sopenharmony_ci		print("Found %d files with invalid include guards:" % len(invalidHeaders))
134e5c31af7Sopenharmony_ci
135e5c31af7Sopenharmony_ci		for header in invalidHeaders:
136e5c31af7Sopenharmony_ci			print("  %s" % header)
137e5c31af7Sopenharmony_ci
138e5c31af7Sopenharmony_ci		if not fix:
139e5c31af7Sopenharmony_ci			sys.exit(-1)
140e5c31af7Sopenharmony_ci	else:
141e5c31af7Sopenharmony_ci		print("All headers have valid include guards.")
142e5c31af7Sopenharmony_ci
143e5c31af7Sopenharmony_ci	if fix:
144e5c31af7Sopenharmony_ci		print("")
145e5c31af7Sopenharmony_ci		for header in invalidHeaders:
146e5c31af7Sopenharmony_ci			fixIncludeGuard(header)
147e5c31af7Sopenharmony_ci			print("Fixed %s" % header)
148