Skip to content

Instantly share code, notes, and snippets.

@qaisjp
Created September 14, 2018 15:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save qaisjp/4f9e80de9b9aa8a21aa952b84e245077 to your computer and use it in GitHub Desktop.
Save qaisjp/4f9e80de9b9aa8a21aa952b84e245077 to your computer and use it in GitHub Desktop.
Python script to remove include guards from files. It also leaves files with exactly one trailing newline.
#! /usr/bin/env python3
import sys, os
def main(args):
if len(args) < 2:
print("./unifdef file1.h file2.h..")
print("Python script to remove include guards from files, and replaces with '#pragma once'.")
print("It also leaves files with exactly one trailing newline.")
print("Use globs with something like zsh to provide lots of arguments")
print("Example: ./unifdef.py Client/**/**.h<tab>")
return
files = args[1:]
for f in files:
if not os.path.isfile(f):
print("{} is not a file".format(f))
continue
process(f)
def process(filepath):
# print("Reading", filepath)
file = open(filepath, "r")
previousLine = ""
lastLine = -1
fileContent = file.read()
lineFeed = file.newlines
newLines = list(fileContent.splitlines())
define = None
for i, l in enumerate(newLines):
l = l + lineFeed
newLines[i] = l
if not define and previousLine != "" and l == previousLine:
define = (previousLine[len("#define "):].strip(), i)
print("Found", filepath, define)
if define:
if l.strip() != "":
previousLine = l
lastLine = i
else:
# only read thirty lines to check for defines
if i >= 30:
break
if l.startswith("#ifndef "):
previousLine = l.replace("#ifndef ", "#define ")
# print(previousLine)
# print(l)
else:
previousLine = ""
define = ""
# print(newLines)
previousLine = previousLine.strip()
if define and previousLine == "#endif":
# Drop this line from the list
linesToDrop = [lastLine, define[1], define[1]-1]
if sorted(linesToDrop, reverse=True) != linesToDrop or any(map(lambda x: x < 0, linesToDrop)):
print("Encountered line parity error with {}, lines are {}", filepath, linesToDrop)
else:
print("Done", filepath, previousLine, len(previousLine), lastLine)
newLines[define[1]-1] = "#pragma once" + lineFeed
newLines[define[1]] = ""
# if lastLine == len(newLines):
# newLines[lastLine] = lineFeed # last line should be a newline
# else:
newLines[lastLine] = ""
# Check last couple of lines to ensure that there is exactly one newline at end
trueLastLine = len(newLines) - 1
startLine = -1
for i in range(trueLastLine-5, len(newLines)):
if startLine == -1 and newLines[i].strip() == "":
startLine = i
elif newLines[i].strip() != "":
startLine = -1
if startLine != -1:
print(startLine, len(newLines))
for i in range(startLine, len(newLines)):
newLines[i] = ""
file.close()
file = open(filepath, "w")
file.write("".join(newLines))
print("")
# print(newLines)
file.close()
if __name__ == "__main__":
main(sys.argv)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment