Nuklear
This is a minimal-state, immediate-mode graphical user interface toolkit written in ANSI C and licensed under public domain. It was designed as a simple embeddable user interface for application and does not have any dependencies, a default render backend or OS window/input handling but instead provides a highly modular, library-based approach, with simple input state for input and draw commands describing primitive shapes as output. So instead of providing a layered library that tries to abstract over a number of platform and render backends, it focuses only on the actual UI.
 
Loading...
Searching...
No Matches
build.py
1
2import fnmatch
3import os.path
4import sys
5import re
6
7def print_help():
8 print(
9"""usage: python single_header_packer.py --macro <macro> [--intro <files>] --extern <files> --pub <files> --priv1 <files> --priv2 <files> [--outro <files>]
10
11 where <files> can be a comma-separated list of files. e.g. --priv *.c,inc/*.h
12 or a space separated list encapsulated in quotes. e.g. --priv1 "file.c file2.c file3.c"
13
14 The 'extern' files are placed between 'priv1' and 'priv2'.
15
16 The resulting code is packed as follows:
17
18 /*
19 [intro file contents]
20 */
21
22 #ifndef <macro>_SINGLE_HEADER
23 #define <macro>_SINGLE_HEADER
24 [public header file contents]
25 #endif /* <macro>_SINGLE_HEADER */
26
27 #ifdef <macro>_IMPLEMENTATION
28 [private header and source file contents]
29 #endif /* <macro>_IMPLEMENTATION */
30
31 /*
32 [outro file contents]
33 */""")
34
35def parse_files(arg):
36 files = []
37 paths = re.split(r'[,\s]', arg)
38
39 for path in paths:
40 if "*" in path:
41 # Wildcard
42 d = os.path.dirname(path)
43 if d == "": d = "."
44 if d == " ": continue
45 if not os.path.exists(d):
46 print(d + " does not exist.")
47 exit()
48
49 wildcard = os.path.basename(path)
50 unsorted = []
51 for file in os.listdir(d):
52 if fnmatch.fnmatch(file, wildcard):
53 unsorted.append(os.path.join(d, file))
54 unsorted.sort()
55 files.extend(unsorted)
56
57 else:
58 # Regular file
59 if not os.path.exists(path):
60 print(path + " does not exist.")
61 exit()
62 elif os.path.isdir(path):
63 print(path + " is a directory. Expected a file name.")
64 exit()
65 else:
66 files.append(path)
67
68 return files;
69
70def omit_includes(str, files):
71 for file in files:
72 fname = os.path.basename(file)
73 if ".h" in file:
74 str = str.replace("#include \"" + fname + "\"", "");
75 str = str.replace("#include <" + fname + ">", "");
76 return str
77
78def fix_comments(str):
79 return re.sub(r"//(.*)(\n|$)", "/* \\1 */\\2", str)
80
81# Main start
82# ==========
83
84if len(sys.argv) < 2:
85 print_help()
86 exit()
87
88intro_files = []
89pub_files = []
90priv_files1 = []
91outro_files2 = []
92extern_files = []
93cur_arg = 1
94macro = ""
95
96# Parse args
97# ----------
98while cur_arg < len(sys.argv):
99 if sys.argv[cur_arg] == "--help":
100 print_help()
101 exit()
102 elif sys.argv[cur_arg] == "--macro":
103 cur_arg += 1
104 macro = sys.argv[cur_arg]
105 elif sys.argv[cur_arg] == "--intro":
106 cur_arg += 1
107 intro_files = parse_files(sys.argv[cur_arg])
108 elif sys.argv[cur_arg] == "--pub":
109 cur_arg += 1
110 pub_files = parse_files(sys.argv[cur_arg])
111 elif sys.argv[cur_arg] == "--priv1":
112 cur_arg += 1
113 priv_files1 = parse_files(sys.argv[cur_arg])
114 elif sys.argv[cur_arg] == "--priv2":
115 cur_arg += 1
116 priv_files2 = parse_files(sys.argv[cur_arg])
117 elif sys.argv[cur_arg] == "--extern":
118 cur_arg += 1
119 extern_files = parse_files(sys.argv[cur_arg])
120 elif sys.argv[cur_arg] == "--outro":
121 cur_arg += 1
122 outro_files = parse_files(sys.argv[cur_arg])
123 else:
124 print("Unknown argument " + sys.argv[cur_arg])
125
126 cur_arg += 1
127
128if macro == "":
129 print("Option --macro <macro> is mandatory")
130 exit()
131
132# Print concatenated output
133# -------------------------
134print("/*")
135for f in intro_files:
136 sys.stdout.write(open(f, 'r').read())
137print("*/")
138
139# print("\n#ifndef " + macro + "_SINGLE_HEADER");
140# print("#define " + macro + "_SINGLE_HEADER");
141print("#ifndef NK_SINGLE_FILE");
142print(" #define NK_SINGLE_FILE");
143print("#endif");
144print("");
145
146for f in pub_files:
147 sys.stdout.write(open(f, 'r').read())
148# print("#endif /* " + macro + "_SINGLE_HEADER */");
149
150print("\n#ifdef " + macro + "_IMPLEMENTATION");
151print("");
152
153for f in priv_files1:
154 print(omit_includes(open(f, 'r').read(),
155 pub_files + priv_files1 + priv_files2 + extern_files))
156for f in extern_files:
157 print(fix_comments(open(f, 'r').read()))
158
159for f in priv_files2:
160 print(omit_includes(open(f, 'r').read(),
161 pub_files + priv_files1 + priv_files2 + extern_files))
162
163print("#endif /* " + macro + "_IMPLEMENTATION */");
164
165print("\n/*")
166for f in outro_files:
167 sys.stdout.write(open(f, 'r').read())
168print("*/\n")
169