# -*- coding: utf-8 -*-
import os
import sys
from fnmatch import fnmatch
from optparse import OptionParser
HEADER_PATTERNS = ["*.hpp", "*.h"]
INDENTED_INCLUDE_PREFIX = "#\tinclude "
IFNDEF_PREFIX = "#ifndef "
def getIncludeGuardName (headerFile):
return '_' + os.path.basename(headerFile).upper().replace('.', '_')
def getRedundantIncludeGuardErrors (fileName):
f = open(fileName, 'rb')
errors = []
lineNumber = 1
prevLine = None
for line in f:
if line.startswith(INDENTED_INCLUDE_PREFIX):
if prevLine is not None and prevLine.startswith(IFNDEF_PREFIX):
ifndefName = prevLine[len(IFNDEF_PREFIX):-1] # \note -1 to take out the newline.
includeName = line[len(INDENTED_INCLUDE_PREFIX)+1:-2] # \note +1 to take out the beginning quote, -2 to take out the newline and the ending quote.
if getIncludeGuardName(includeName) != ifndefName:
errors.append("Invalid redundant include guard around line %d:" % lineNumber)
errors.append("guard is %s but included file is %s" % (ifndefName, includeName))
prevLine = line
lineNumber += 1
f.close()
return errors
def isHeader (filename):
for pattern in HEADER_PATTERNS:
if fnmatch(filename, pattern):
return True
return False
def getFileList (path):
allFiles = []
if os.path.isfile(path):
if isHeader(path):
allFiles.append(path)
else:
for root, dirs, files in os.walk(path):
for file in files:
if isHeader(file):
allFiles.append(os.path.join(root, file))
return allFiles
if __name__ == "__main__":
parser = OptionParser()
parser.add_option("-q", "--quiet", action="store_true", dest="quiet", default=False, help="only print files with errors")
(options, args) = parser.parse_args()
quiet = options.quiet
files = []
invalidFiles = []
for dir in args:
files += getFileList(os.path.normpath(dir))
print "Checking..."
for file in files:
if not quiet:
print " %s" % file
errors = getRedundantIncludeGuardErrors(file)
if errors:
if quiet:
print " %s" % file
for err in errors:
print " %s" % err
invalidFiles.append(file)
print ""
if len(invalidFiles) > 0:
print "Found %d files with invalid redundant include guards:" % len(invalidFiles)
for file in invalidFiles:
print " %s" % file
sys.exit(-1)
else:
print "All files have valid redundant include guards."