Skip to content

Commit

Permalink
Added single_header_packer.py
Browse files Browse the repository at this point in the history
  • Loading branch information
Apoorva committed Apr 2, 2018
1 parent fa5a0f7 commit e35ca3c
Showing 1 changed file with 138 additions and 0 deletions.
138 changes: 138 additions & 0 deletions scripts/single_header_packer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@

import fnmatch
import os.path
import sys

def print_help():
print(
"""usage: python single_header_packer.py --macro <macro> [--intro <files>] --pub <files> --priv <files> [--outro <files>]
where <files> can be a comma-separated list of files. e.g. --priv *.c,inc/*.h
The resulting code is packed as follows:
/*
[intro file contents]
*/
#ifndef <macro>_SINGLE_HEADER
#define <macro>_SINGLE_HEADER
[public header file contents]
#endif /* <macro>_SINGLE_HEADER */
#ifdef <macro>_IMPLEMENTATION
[private header and source file contents]
#endif /* <macro>_IMPLEMENTATION */
/*
[outro file contents]
*/""")

def parse_files(arg):
files = []
paths = arg.split(",")
for path in paths:
if "*" in path:
# Wildcard
d = os.path.dirname(path)
if d == "": d = "."
if not os.path.exists(d):
print(d + " does not exist.")
exit()

wildcard = os.path.basename(path)
unsorted = []
for file in os.listdir(d):
if fnmatch.fnmatch(file, wildcard):
unsorted.append(os.path.join(d, file))
unsorted.sort()
files.extend(unsorted)

else:
# Regular file
if not os.path.exists(path):
print(path + " does not exist.")
exit()
elif os.path.isdir(path):
print(path + " is a directory. Expected a file name.")
exit()
else:
files.append(path)

return files;

def omit_includes(str, files):
for file in files:
fname = os.path.basename(file)
if ".h" in file:
str = str.replace("#include \"" + fname + "\"", "");
str = str.replace("#include <" + fname + ">", "");
return str

# Main start
# ==========

if len(sys.argv) < 2:
print_help()
exit()

intro_files = []
pub_files = []
priv_files = []
outro_files = []
cur_arg = 1
macro = ""

# Parse args
# ----------
while cur_arg < len(sys.argv):
if sys.argv[cur_arg] == "--help":
print_help()
exit()
elif sys.argv[cur_arg] == "--macro":
cur_arg += 1
macro = sys.argv[cur_arg]
elif sys.argv[cur_arg] == "--intro":
cur_arg += 1
intro_files = parse_files(sys.argv[cur_arg])
elif sys.argv[cur_arg] == "--pub":
cur_arg += 1
pub_files = parse_files(sys.argv[cur_arg])
elif sys.argv[cur_arg] == "--priv":
cur_arg += 1
priv_files = parse_files(sys.argv[cur_arg])
elif sys.argv[cur_arg] == "--outro":
cur_arg += 1
outro_files = parse_files(sys.argv[cur_arg])
else:
print("Unknown argument " + sys.argv[cur_arg])

cur_arg += 1

if macro == "":
print("Option --macro <macro> is mandatory")
exit()

# Print concatenated output
# -------------------------
print(os.linesep * 2 + "/*")
for f in intro_files:
sys.stdout.write(open(f, 'r').read())
print("*/")

print(os.linesep + "#ifndef " + macro + "_SINGLE_HEADER");
print("#define " + macro + "_SINGLE_HEADER");
for f in pub_files:
sys.stdout.write(open(f, 'r').read())
print("#endif /* " + macro + "_SINGLE_HEADER */");

print(os.linesep + "#ifdef " + macro + "_IMPLEMENTATION");
for f in priv_files:
print(omit_includes(open(f, 'r').read(),
pub_files + priv_files))
print("#endif /* " + macro + "_IMPLEMENTATION */");

print(os.linesep + "/*")
for f in outro_files:
sys.stdout.write(open(f, 'r').read())
print("*/" + os.linesep)

0 comments on commit e35ca3c

Please sign in to comment.