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