Blame src-nuklear/build.py

Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
import fnmatch
Ivan Mahonin b53a5c
import os.path
Ivan Mahonin b53a5c
import sys
Ivan Mahonin b53a5c
import re
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
def print_help():
Ivan Mahonin b53a5c
    print(
Ivan Mahonin b53a5c
"""usage: python single_header_packer.py --macro <macro> [--intro <files>] --extern <files> --pub <files> --priv1 <files> --priv2 <files> [--outro <files>]
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
       where <files> can be a comma-separated list of files. e.g. --priv *.c,inc/*.h
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
       The 'extern' files are placed between 'priv1' and 'priv2'.
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
       The resulting code is packed as follows:
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
           /*
Ivan Mahonin b53a5c
           [intro file contents]
Ivan Mahonin b53a5c
           */
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
           #ifndef <macro>_SINGLE_HEADER
Ivan Mahonin b53a5c
           #define <macro>_SINGLE_HEADER
Ivan Mahonin b53a5c
           [public header file contents]
Ivan Mahonin b53a5c
           #endif /* <macro>_SINGLE_HEADER */
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
           #ifdef <macro>_IMPLEMENTATION
Ivan Mahonin b53a5c
           [private header and source file contents]
Ivan Mahonin b53a5c
           #endif /* <macro>_IMPLEMENTATION */
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
           /*
Ivan Mahonin b53a5c
           [outro file contents]
Ivan Mahonin b53a5c
           */""")
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
def parse_files(arg):
Ivan Mahonin b53a5c
    files = []
Ivan Mahonin b53a5c
    paths = arg.split(",")
Ivan Mahonin b53a5c
    for path in paths:
Ivan Mahonin b53a5c
        if "*" in path:
Ivan Mahonin b53a5c
            # Wildcard
Ivan Mahonin b53a5c
            d = os.path.dirname(path)
Ivan Mahonin b53a5c
            if d == "": d = "."
Ivan Mahonin b53a5c
            if d == " ": continue
Ivan Mahonin b53a5c
            if not os.path.exists(d):
Ivan Mahonin b53a5c
                print(d + " does not exist.")
Ivan Mahonin b53a5c
                exit()
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
            wildcard = os.path.basename(path)
Ivan Mahonin b53a5c
            unsorted = []
Ivan Mahonin b53a5c
            for file in os.listdir(d):
Ivan Mahonin b53a5c
                if fnmatch.fnmatch(file, wildcard):
Ivan Mahonin b53a5c
                    unsorted.append(os.path.join(d, file))
Ivan Mahonin b53a5c
            unsorted.sort()
Ivan Mahonin b53a5c
            files.extend(unsorted)
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
        else:
Ivan Mahonin b53a5c
            # Regular file
Ivan Mahonin b53a5c
            if not os.path.exists(path):
Ivan Mahonin b53a5c
                print(path + " does not exist.")
Ivan Mahonin b53a5c
                exit()
Ivan Mahonin b53a5c
            elif os.path.isdir(path):
Ivan Mahonin b53a5c
                print(path + " is a directory. Expected a file name.")
Ivan Mahonin b53a5c
                exit()
Ivan Mahonin b53a5c
            else:
Ivan Mahonin b53a5c
                files.append(path)
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    return files;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
def omit_includes(str, files):
Ivan Mahonin b53a5c
    for file in files:
Ivan Mahonin b53a5c
        fname = os.path.basename(file)
Ivan Mahonin b53a5c
        if ".h" in file:
Ivan Mahonin b53a5c
            str = str.replace("#include \"" + fname + "\"", "");
Ivan Mahonin b53a5c
            str = str.replace("#include <" + fname + ">", "");
Ivan Mahonin b53a5c
    return str
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
def fix_comments(str):
Ivan Mahonin b53a5c
    return re.sub(r"//(.*)(\n|$)", "/* \\1 */\\2", str)
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
# Main start
Ivan Mahonin b53a5c
# ==========
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
if len(sys.argv) < 2:
Ivan Mahonin b53a5c
    print_help()
Ivan Mahonin b53a5c
    exit()
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
intro_files = []
Ivan Mahonin b53a5c
pub_files = []
Ivan Mahonin b53a5c
priv_files1 = []
Ivan Mahonin b53a5c
outro_files2 = []
Ivan Mahonin b53a5c
extern_files = []
Ivan Mahonin b53a5c
cur_arg = 1
Ivan Mahonin b53a5c
macro = ""
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
# Parse args
Ivan Mahonin b53a5c
# ----------
Ivan Mahonin b53a5c
while cur_arg < len(sys.argv):
Ivan Mahonin b53a5c
    if sys.argv[cur_arg] == "--help":
Ivan Mahonin b53a5c
        print_help()
Ivan Mahonin b53a5c
        exit()
Ivan Mahonin b53a5c
    elif sys.argv[cur_arg] == "--macro":
Ivan Mahonin b53a5c
        cur_arg += 1
Ivan Mahonin b53a5c
        macro = sys.argv[cur_arg]
Ivan Mahonin b53a5c
    elif sys.argv[cur_arg] == "--intro":
Ivan Mahonin b53a5c
        cur_arg += 1
Ivan Mahonin b53a5c
        intro_files = parse_files(sys.argv[cur_arg])
Ivan Mahonin b53a5c
    elif sys.argv[cur_arg] == "--pub":
Ivan Mahonin b53a5c
        cur_arg += 1
Ivan Mahonin b53a5c
        pub_files = parse_files(sys.argv[cur_arg])
Ivan Mahonin b53a5c
    elif sys.argv[cur_arg] == "--priv1":
Ivan Mahonin b53a5c
        cur_arg += 1
Ivan Mahonin b53a5c
        priv_files1 = parse_files(sys.argv[cur_arg])
Ivan Mahonin b53a5c
    elif sys.argv[cur_arg] == "--priv2":
Ivan Mahonin b53a5c
        cur_arg += 1
Ivan Mahonin b53a5c
        priv_files2 = parse_files(sys.argv[cur_arg])
Ivan Mahonin b53a5c
    elif sys.argv[cur_arg] == "--extern":
Ivan Mahonin b53a5c
        cur_arg += 1
Ivan Mahonin b53a5c
        extern_files = parse_files(sys.argv[cur_arg])
Ivan Mahonin b53a5c
    elif sys.argv[cur_arg] == "--outro":
Ivan Mahonin b53a5c
        cur_arg += 1
Ivan Mahonin b53a5c
        outro_files = parse_files(sys.argv[cur_arg])
Ivan Mahonin b53a5c
    else:
Ivan Mahonin b53a5c
        print("Unknown argument " + sys.argv[cur_arg])
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    cur_arg += 1
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
if macro == "":
Ivan Mahonin b53a5c
    print("Option --macro <macro> is mandatory")
Ivan Mahonin b53a5c
    exit()
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
# Print concatenated output
Ivan Mahonin b53a5c
# -------------------------
Ivan Mahonin b53a5c
print("/*")
Ivan Mahonin b53a5c
for f in intro_files:
Ivan Mahonin b53a5c
    sys.stdout.write(open(f, 'r').read())
Ivan Mahonin b53a5c
print("*/")
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
# print("\n#ifndef " + macro + "_SINGLE_HEADER");
Ivan Mahonin b53a5c
# print("#define " + macro + "_SINGLE_HEADER");
Ivan Mahonin b53a5c
print("#ifndef NK_SINGLE_FILE");
Ivan Mahonin b53a5c
print("  #define NK_SINGLE_FILE");
Ivan Mahonin b53a5c
print("#endif");
Ivan Mahonin b53a5c
print("");
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
for f in pub_files:
Ivan Mahonin b53a5c
    sys.stdout.write(open(f, 'r').read())
Ivan Mahonin b53a5c
# print("#endif /* " + macro + "_SINGLE_HEADER */");
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
print("\n#ifdef " + macro + "_IMPLEMENTATION");
Ivan Mahonin b53a5c
print("");
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
for f in priv_files1:
Ivan Mahonin b53a5c
    print(omit_includes(open(f, 'r').read(),
Ivan Mahonin b53a5c
                        pub_files + priv_files1 + priv_files2 + extern_files))
Ivan Mahonin b53a5c
for f in extern_files:
Ivan Mahonin b53a5c
    print(fix_comments(open(f, 'r').read()))
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
for f in priv_files2:
Ivan Mahonin b53a5c
    print(omit_includes(open(f, 'r').read(),
Ivan Mahonin b53a5c
                        pub_files + priv_files1 + priv_files2 + extern_files))
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
print("#endif /* " + macro + "_IMPLEMENTATION */");
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
print("\n/*")
Ivan Mahonin b53a5c
for f in outro_files:
Ivan Mahonin b53a5c
    sys.stdout.write(open(f, 'r').read())
Ivan Mahonin b53a5c
print("*/\n")
Ivan Mahonin b53a5c