-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathincludeHeaderCodegen.py
161 lines (135 loc) · 6.63 KB
/
includeHeaderCodegen.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#copyright
## @author Marc Greim <[email protected]>
import sys
from os import listdir
from os.path import isfile, isdir, join, relpath,abspath
import argparse
def to_hex_carray(s):
return "{" + ",".join(("0x" + ("{:02x}".format(ord(c)))) for c in (s + "\x00")) + "}"
def addFile(base_path,f,data):
with open(f,"r") as header:
data.append([relpath(f,base_path),header.read(),f])
def travel_rec(base_path,cur_path,data):
for f in [ f for f in listdir(cur_path) if isfile(join(cur_path,f)) ]:
addFile(base_path,join(cur_path,f),data)
for f in [ f for f in listdir(cur_path) if isdir(join(cur_path,f)) ]:
travel_rec(base_path,join(cur_path,f),data)
def list_folders_rec(path):
ret = []
ret.append(path)
for f in [ f for f in listdir(path) if isdir(join(path,f)) ]:
ret.extend(list_folders_rec(join(path,f)))
return ret
def gen_full_name(namespaces,name):
d = []
for ns in namespaces:
d.append(ns[0])
d.append(name)
return "::".join(d)
def gen_localfull_name(namespaces,name):
d = []
for ns in namespaces:
d.append(ns[0])
d.append(name)
return "_".join(d)
def gen_cpp(f,lvar,nvar,dvar,namespaces,data,includeHeader):
#notice
f.write("// NOTE: this file was generated by includeHeaderCodegen.py. DO NOT MODIFY.\n\n\n")
#copyright
f.write("\n")
#author
f.write("/**\n\t@author Marc Greim <[email protected]>\n*/\n\n")
if includeHeader is None:
f.write("//////////////////////////////////////////////////////////////\n")
f.write("//HEADER DEFINITIONS\n")
f.write("//////////////////////////////////////////////////////////////\n")
gen_h(f,lvar,nvar,dvar,namespaces,len(data))
f.write("//////////////////////////////////////////////////////////////")
else:
f.write("#include \""+includeHeader+"\"\n\n")
#header file count
f.write("const int "+gen_full_name(namespaces,lvar)+" = ")
f.write(str(len(data)));
f.write(";\n")
#header file names
for i in range(len(data)):
f.write("const unsigned char "+gen_full_name(namespaces,nvar)+"_"+str(i)+"[] = "+to_hex_carray(data[i][0])+";\n")
f.write("const char * "+gen_full_name(namespaces,nvar)+"[] = {\n\t")
f.write(",\n\t".join("(const char *) "+(gen_full_name(namespaces,nvar)+"_"+str(i)) for i in range(len(data))))
f.write("\n};\n")
#header contents
for i in range(len(data)):
f.write("const unsigned char "+gen_full_name(namespaces,dvar)+"_"+str(i)+"[] = "+to_hex_carray(data[i][1])+";\n")
f.write("const char * "+gen_full_name(namespaces,dvar)+"[] = {\n\t")
f.write(",\n\t".join(("(const char *) "+gen_full_name(namespaces,dvar)+"_"+str(i)) for i in range(len(data))))
f.write("\n};\n")
#header contents
f.write("int "+gen_full_name(namespaces,dvar+"_size")+"[] = {\n\t")
for i in range(len(data)):
f.write(str(len(data[i][1]))+",\n")
f.write("0\n};\n")
def gen_h(f,lvar,nvar,dvar,namespaces,dataLength):
#notice
f.write("// NOTE: this file was generated by includeHeaderCodegen.py. DO NOT MODIFY.\n\n\n")
#copyright
f.write("\n")
#author
f.write("/**\n\t@author Marc Greim <[email protected]>\n*/\n\n")
#namespace
for ns in namespaces:
f.write("namespace "+ns[0]+"{\n")
#header file count
f.write("extern const int "+lvar+";\n")
#header file names
for i in range(dataLength):
f.write("extern const unsigned char "+nvar+"_"+str(i)+"[];\n")
f.write("extern const char * "+nvar+"[];\n")
#header contents
for i in range(len(data)):
f.write("extern const unsigned char "+dvar+"_"+str(i)+"[];\n")
f.write("extern const char * "+dvar+"[];\n")
#header content size
f.write("extern int "+dvar+"_size[];\n")
#/namespace
for ns in namespaces:
f.write("}\n")
parser = argparse.ArgumentParser()
parser.add_argument('-f','--file',type=str,action="append",nargs=2,default=[],help='Add a single file that will be stored in the generated code file.File paths are stored relative to BaseFolder.',metavar=('BaseFolder', 'File'))
parser.add_argument('-s','--store',type=str,action="append",nargs=2,default=[],help='Adds files that will be stored in the generated code file.File paths are stored relative to BaseFolder.',metavar=('BaseFolder', 'FolderToScan'))
parser.add_argument('-a','--storeAll',type=str,action="append",nargs=1,default=[],help='Adds files that will be stored in the generated code file.File paths are stored relative to this folder.',metavar=('FolderToScan'))
parser.add_argument('-ns','--namespace',type=str,action="append",nargs=1,default=[],help='defines the variables in a namspace. nested namespaces can be used by adding [-ns namespace] multiple times: e.g. -ns namespaceOuter -ns namepaceInner',metavar=('namespace'))
parser.add_argument('-l','--arrayLengthVariable',type=str,action="store",nargs=1,default=['_inluce_c_header_count'],help='Sets the name of the array length variable of file names and file data arrays',metavar=('name'))
parser.add_argument('-n','--fileNameArray',type=str,action="store",nargs=1,default=['_inluce_c_header_names'],help='Sets the variable name of the file name array',metavar=('name'))
parser.add_argument('-d','--fileDataArray',type=str,action="store",nargs=1,default=['_inluce_c_header_data'],help='Sets the variable name of the file name array',metavar=('name'))
parser.add_argument('-mkd','--makeDependency',type=str,nargs=2,help='Sets the target file for the .d file to include in a makefile. The second parameter is the target name that runs this script',metavar=('dFile','targetName'))
parser.add_argument('-ch','--createHeader',type=str,action="store",nargs=2,help='Creates an optional header file defining the variables',metavar=('file','includename'))
parser.add_argument('outputFile',type=str,help='Target file for the generated C code containing the stored files added via -s')
args = parser.parse_args()
data = []
for s in args.store:
travel_rec(s[0],s[1],data)
for a in args.storeAll:
travel_rec(a,a,data)
for f in args.file:
addFile(f[0],f[1],data)
if args.makeDependency is not None:
with open(args.makeDependency[0],"w+") as f:
f.write(args.makeDependency[1]+": \\\n")
for e in data:
f.write("\t"+abspath(e[2])+" \\\n")
for s in args.store:
for e in list_folders_rec(s[1]):
f.write("\t"+abspath(e)+" \\\n")
for a in args.storeAll:
for e in list_folders_rec(a):
f.write("\t"+abspath(e)+" \\\n")
includeHeader = None
if args.createHeader is not None:
includeHeader = args.createHeader[1]
with open (args.createHeader[0],"w+") as f:
gen_h(f,args.arrayLengthVariable[0],args.fileNameArray[0],args.fileDataArray[0],args.namespace,len(data))
with open(args.outputFile,"w+") as f:
gen_cpp(f,args.arrayLengthVariable[0],args.fileNameArray[0],args.fileDataArray[0],args.namespace,data,includeHeader)
print "NOTE: the following files have been included:"
for e in data:
print "\t\t" + e[0] + " [local file: " + e[2] + "]"