# -*- coding: utf-8 -*-
#-------------------------------------------------------------------------
# drawElements Quality Program utilities
# --------------------------------------
#
# Copyright 2015 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#-------------------------------------------------------------------------
import os
import sys
from fnmatch import fnmatch
from optparse import OptionParser
HEADER_PATTERNS = ["*.hpp", "*.h"]
CHECK_END_COMMENT = True
def getIncludeGuardName (headerFile):
return '_' + os.path.basename(headerFile).upper().replace('.', '_')
def hasValidIncludeGuard (headerFile):
includeGuard = getIncludeGuardName(headerFile)
f = open(headerFile, 'rb')
isHpp = headerFile[-4:] == ".hpp"
line0 = f.readline().strip()
line1 = f.readline().strip()
if line0 != ("#ifndef %s" % includeGuard):
return False
if line1 != ("#define %s" % includeGuard):
return False
if CHECK_END_COMMENT:
lastLine = ""
expectedComment = ("#endif // %s" if isHpp else "#endif /* %s */") % includeGuard
for line in f:
lastLine = line.strip()
if lastLine != expectedComment:
# print "'%s' != '%s'" % (lastLine, expectedComment)
return False
f.close()
return True
def fixIncludeGuard (headerFile):
f = open(headerFile, 'rb')
lines = []
isHpp = headerFile[-4:] == ".hpp"
includeGuard = getIncludeGuardName(headerFile)
for line in f:
lines.append(line)
f.close()
# Replace include guards
lines[0] = "#ifndef %s\n" % includeGuard
lines[1] = "#define %s\n" % includeGuard
if CHECK_END_COMMENT:
lines[len(lines)-1] = ("#endif // %s\n" if isHpp else "#endif /* %s */\n") % includeGuard
f = open(headerFile, 'wb')
for line in lines:
f.write(line)
f.close()
def isHeader (filename):
for pattern in HEADER_PATTERNS:
if fnmatch(filename, pattern):
return True
return False
def getHeaderFileList (path):
headers = []
if os.path.isfile(path):
if isHeader(path):
headers.append(path)
else:
for root, dirs, files in os.walk(path):
for file in files:
if isHeader(file):
headers.append(os.path.join(root, file))
return headers
def checkIncludeGuards (files):
error = False
for file in files:
if isHeader(file):
if not hasValidIncludeGuard(file):
error = True
print "File %s contains invalid include guards" % file
return not error
if __name__ == "__main__":
parser = OptionParser()
parser.add_option("-x", "--fix", action="store_true", dest="fix", default=False, help="attempt to fix include guards (use with caution)")
(options, args) = parser.parse_args()
fix = options.fix
headers = []
invalidHeaders = []
for dir in args:
headers += getHeaderFileList(os.path.normpath(dir))
print "Checking..."
for header in headers:
print " %s" % header
if not hasValidIncludeGuard(header):
invalidHeaders.append(header)
print ""
if len(invalidHeaders) > 0:
print "Found %d files with invalid include guards:" % len(invalidHeaders)
for header in invalidHeaders:
print " %s" % header
if not fix:
sys.exit(-1)
else:
print "All headers have valid include guards."
if fix:
print ""
for header in invalidHeaders:
fixIncludeGuard(header)
print "Fixed %s" % header