# -*- coding: utf-8 -*- 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 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