104 lines
3.4 KiB
Python
104 lines
3.4 KiB
Python
|
# This scripts generates single header doom.
|
||
|
|
||
|
|
||
|
import glob
|
||
|
import re
|
||
|
import os
|
||
|
|
||
|
|
||
|
files = []
|
||
|
code_files = []
|
||
|
done_files = []
|
||
|
final:str = ""
|
||
|
|
||
|
|
||
|
class File:
|
||
|
def __init__(self, filename) -> None:
|
||
|
with open(filename, "r") as file:
|
||
|
self.content = file.read()
|
||
|
|
||
|
# Find headers
|
||
|
self.headers = re.findall(r'#include \"(\w+\.h)\"', self.content)
|
||
|
|
||
|
# Comment out includes
|
||
|
# Special handling is needed for DOOM.c. It includes system headers, and
|
||
|
# we can't comment those out. For DOOM.c, only comment out quoted
|
||
|
# includes. Otherwise, comment all of them.
|
||
|
if os.path.basename(filename) == "DOOM.c":
|
||
|
self.content = re.sub(r'#include[ \t]+\"', '//#include "', self.content)
|
||
|
else:
|
||
|
self.content = re.sub(r'#include', '//#include', self.content)
|
||
|
|
||
|
# Remove copyrighted block of text at the top (We include copyright at the top of the PureDOOM.h)
|
||
|
# This is done by finding the first non-empty line that doesn't start with `//`
|
||
|
# Note the use of `:=`: https://docs.python.org/3/whatsnew/3.8.html#assignment-expressions
|
||
|
if (match := re.search(r'(^|\n)(?!//|\n)', self.content)) is not None:
|
||
|
# Get rid of everything up to and including the first match
|
||
|
# This works because the match is for the character preceeding where
|
||
|
# we should start - either `^` or the preceeding newline.
|
||
|
self.content = self.content[match.end():]
|
||
|
|
||
|
# Clean up some "logs" at the end of the file
|
||
|
self.content = re.sub(r'\/\/-----------------------------------------------------------------------------\n\/\/\n\/\/ \$Log\:\$\n\/\/\n\/\/-----------------------------------------------------------------------------', '', self.content)
|
||
|
|
||
|
self.name = os.path.basename(filename)
|
||
|
|
||
|
def __repr__(self) -> str:
|
||
|
return self.name + " -> " + str(self.headers)
|
||
|
|
||
|
|
||
|
# Collect headers
|
||
|
headers = glob.glob(r'../src/DOOM/*.h')
|
||
|
headers.sort() # To make it predictable
|
||
|
for header in headers:
|
||
|
if header.endswith("DOOM.h") or header.endswith("d_french.h"):
|
||
|
continue # We'll do that one manually later, and first
|
||
|
files.append(File(header))
|
||
|
|
||
|
# Collect code files
|
||
|
codes = glob.glob(r'../src/DOOM/*.c')
|
||
|
codes.sort() # To make it predictable
|
||
|
for code in codes:
|
||
|
code_files.append(File(code))
|
||
|
|
||
|
# Start with DOOM.h
|
||
|
with open("../src/DOOM/DOOM.h", "r") as header:
|
||
|
final += header.read()
|
||
|
print("Concat: DOOM.h")
|
||
|
done_files.append("DOOM.h")
|
||
|
|
||
|
# Concat files as long as there are to concat
|
||
|
while len(files) > 0:
|
||
|
# Find the first file where it's dependencies have been done
|
||
|
found = False
|
||
|
for file in files:
|
||
|
has_dependencies = False
|
||
|
for header in file.headers:
|
||
|
if header not in done_files:
|
||
|
has_dependencies = True
|
||
|
break
|
||
|
if has_dependencies:
|
||
|
continue # Pick a different file
|
||
|
found = True
|
||
|
print("Concat: " + file.name)
|
||
|
final += file.content
|
||
|
done_files.append(file.name)
|
||
|
files.remove(file)
|
||
|
break
|
||
|
if not found:
|
||
|
print("Cycling includes: " + str(files))
|
||
|
exit(1)
|
||
|
|
||
|
final += "\n#if defined(DOOM_IMPLEMENTATION)\n"
|
||
|
|
||
|
# Append all code files after
|
||
|
for file in code_files:
|
||
|
print("Concat: " + file.name)
|
||
|
final += file.content
|
||
|
|
||
|
final += "\n#endif // DOOM_IMPLEMENTATION\n"
|
||
|
|
||
|
# Output single header
|
||
|
with open("../PureDOOM.h", "w") as file:
|
||
|
file.write(final)
|