# -*- 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"] IGNORE_FILES = set(["tcuEAGLView.h", "tcuIOSAppDelegate.h", "tcuIOSViewController.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): if os.path.basename(filename) in IGNORE_FILES: return False 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