Update gen_ostream_ops.py
New version of script generates all expected fields for KFD API. I checked all structs and made sure nested structs and unions, named or anonymous are handled properly.
This commit is contained in:
+74
-103
@@ -32,67 +32,104 @@ HEADER = \
|
||||
'struct output_streamer {\n' + \
|
||||
' inline static std::ostream& put(std::ostream& out, const T& v) { return out; }\n' + \
|
||||
'};\n' + \
|
||||
'template<>\n' + \
|
||||
'\ntemplate<>\n' + \
|
||||
'struct output_streamer<bool> {\n' + \
|
||||
' inline static std::ostream& put(std::ostream& out, bool v) { out << std::hex << "<bool " << "0x" << v << std::dec << ">"; return out; }\n' + \
|
||||
'};\n' + \
|
||||
'template<>\n' + \
|
||||
'\ntemplate<>\n' + \
|
||||
'struct output_streamer<uint8_t> {\n' + \
|
||||
' inline static std::ostream& put(std::ostream& out, uint8_t v) { out << std::hex << "<uint8_t " << "0x" << v << std::dec << ">"; return out; }\n' + \
|
||||
'};\n' + \
|
||||
'template<>\n' + \
|
||||
'\ntemplate<>\n' + \
|
||||
'struct output_streamer<uint16_t> {\n' + \
|
||||
' inline static std::ostream& put(std::ostream& out, uint16_t v) { out << std::hex << "<uint16_t " << "0x" << v << std::dec << ">"; return out; }\n' + \
|
||||
'};\n' + \
|
||||
'template<>\n' + \
|
||||
'\ntemplate<>\n' + \
|
||||
'struct output_streamer<uint32_t> {\n' + \
|
||||
' inline static std::ostream& put(std::ostream& out, uint32_t v) { out << std::hex << "<uint32_t " << "0x" << v << std::dec << ">"; return out; }\n' + \
|
||||
'};\n' + \
|
||||
'template<>\n' + \
|
||||
'\ntemplate<>\n' + \
|
||||
'struct output_streamer<uint64_t> {\n' + \
|
||||
' inline static std::ostream& put(std::ostream& out, uint64_t v) { out << std::hex << "<uint64_t " << "0x" << v << std::dec << ">"; return out; }\n' + \
|
||||
'};\n' + \
|
||||
'\n' + \
|
||||
'template<>\n' + \
|
||||
'\ntemplate<>\n' + \
|
||||
'struct output_streamer<bool*> {\n' + \
|
||||
' inline static std::ostream& put(std::ostream& out, bool* v) { out << std::hex << "<bool " << "0x" << *v << std::dec << ">"; return out; }\n' + \
|
||||
'};\n' + \
|
||||
'template<>\n' + \
|
||||
'\ntemplate<>\n' + \
|
||||
'struct output_streamer<uint8_t*> {\n' + \
|
||||
' inline static std::ostream& put(std::ostream& out, uint8_t* v) { out << std::hex << "<uint8_t " << "0x" << *v << std::dec << ">"; return out; }\n' + \
|
||||
'};\n' + \
|
||||
'template<>\n' + \
|
||||
'\ntemplate<>\n' + \
|
||||
'struct output_streamer<uint16_t*> {\n' + \
|
||||
' inline static std::ostream& put(std::ostream& out, uint16_t* v) { out << std::hex << "<uint16_t " << "0x" << *v << std::dec << ">"; return out; }\n' + \
|
||||
'};\n' + \
|
||||
'template<>\n' + \
|
||||
'\ntemplate<>\n' + \
|
||||
'struct output_streamer<uint32_t*> {\n' + \
|
||||
' inline static std::ostream& put(std::ostream& out, uint32_t* v) { out << std::hex << "<uint32_t " << "0x" << *v << std::dec << ">"; return out; }\n' + \
|
||||
'};\n' + \
|
||||
'template<>\n' + \
|
||||
'\ntemplate<>\n' + \
|
||||
'struct output_streamer<uint64_t*> {\n' + \
|
||||
' inline static std::ostream& put(std::ostream& out, uint64_t* v) { out << std::hex << "<uint64_t " << "0x" << *v << std::dec << ">"; return out; }\n' + \
|
||||
'};\n' + \
|
||||
'\n'
|
||||
|
||||
rx_dict = {
|
||||
'struct_name': re.compile(r'typedef (?P<struct_name>.*)\n'),
|
||||
'field_type': re.compile(r'\s+name\[type\]=(?P<field_type>.*)\n'),
|
||||
'field_rawtype': re.compile(r'\s+name\[raw_type\]=(?P<field_rawtype>.*)\n'),
|
||||
'field_name': re.compile(r'\s+name\[name\]=(?P<field_name>.*)\n'),
|
||||
'array_size_val': re.compile(r'\s+name\[array_size\]=(?P<array_size_val>.*)\n'),
|
||||
}
|
||||
structs_done={}
|
||||
def process_struct(f,c,cppHeader,nname):
|
||||
|
||||
def _parse_line(line):
|
||||
if c not in cppHeader.classes:
|
||||
return
|
||||
if c in structs_done:
|
||||
return
|
||||
|
||||
for key, rx in rx_dict.items():
|
||||
match = rx.search(line)
|
||||
if match:
|
||||
return key, match
|
||||
return None, None
|
||||
structs_done[c]=1;
|
||||
for l in range(len(cppHeader.classes[c]["properties"]["public"])):
|
||||
key='name'
|
||||
name=""
|
||||
if key in cppHeader.classes[c]["properties"]["public"][l]:
|
||||
name = cppHeader.classes[c]["properties"]["public"][l][key]
|
||||
key2='type'
|
||||
mtype=""
|
||||
if key2 in cppHeader.classes[c]["properties"]["public"][l]:
|
||||
mtype = cppHeader.classes[c]["properties"]["public"][l][key2]
|
||||
key3='array_size'
|
||||
array_size=""
|
||||
if key3 in cppHeader.classes[c]["properties"]["public"][l]:
|
||||
array_size=cppHeader.classes[c]["properties"]["public"][l][key3]
|
||||
key4='property_of_class'
|
||||
prop=""
|
||||
if key4 in cppHeader.classes[c]["properties"]["public"][l]:
|
||||
prop=cppHeader.classes[c]["properties"]["public"][l][key4]
|
||||
|
||||
def parse_file(infilepath,outfilepath):
|
||||
f = open(outfilepath,"w+")
|
||||
if mtype!="" and "union" not in mtype:
|
||||
if array_size == "":
|
||||
str=" roctracer::kfd_support::output_streamer<"+mtype+">::put(out,v."+name+");\n"
|
||||
else:
|
||||
str=" roctracer::kfd_support::output_streamer<"+mtype+"["+array_size+"]>::put(out,v."+name+");\n"
|
||||
|
||||
if nname!="" and nname not in str:
|
||||
#print("injecting ",nname, "in ", str)
|
||||
str=str.replace("v.","v."+nname+".")
|
||||
if "void" not in mtype:
|
||||
f.write(str)
|
||||
else:
|
||||
nc=prop+"::"
|
||||
process_struct(f,nc,cppHeader,name)
|
||||
nc=prop+"::"+mtype+" "
|
||||
process_struct(f,nc,cppHeader,name)
|
||||
nc=c+"::"
|
||||
process_struct(f,nc,cppHeader,name)
|
||||
|
||||
|
||||
def gen_cppheader(infilepath,outfilepath):
|
||||
try:
|
||||
cppHeader = CppHeaderParser.CppHeader(infilepath)
|
||||
except CppHeaderParser.CppParseError as e:
|
||||
print(e)
|
||||
sys.exit(1)
|
||||
|
||||
f= open(outfilepath,"w+")
|
||||
f.write("// automatically generated\n")
|
||||
f.write(LICENSE)
|
||||
f.write("\n")
|
||||
@@ -105,71 +142,24 @@ def parse_file(infilepath,outfilepath):
|
||||
'#include "hsakmt.h"\n'
|
||||
f.write(HEADER_S)
|
||||
f.write('\n')
|
||||
f.write('namespace roctracer {\n')
|
||||
f.write('namespace roctracer {\n')
|
||||
f.write('namespace kfd_support {\n')
|
||||
f.write('// begin ostream ops for KFD \n')
|
||||
f.write(HEADER)
|
||||
|
||||
with open(infilepath, 'r') as file_object:
|
||||
line = file_object.readline()
|
||||
flag=0
|
||||
tmp_str=""
|
||||
while line:
|
||||
key, match = _parse_line(line)
|
||||
if key == 'struct_name':
|
||||
field_name=""
|
||||
field_type=""
|
||||
field_rawtype=""
|
||||
if tmp_str!="":
|
||||
f.write(tmp_str+"\n")
|
||||
tmp_str=""
|
||||
if flag == 1:
|
||||
f.write(" return out;\n")
|
||||
f.write("}\n")
|
||||
f.write("};\n")
|
||||
flag=0
|
||||
struct_name = match.group('struct_name')
|
||||
if ("anon" not in struct_name and "union" not in struct_name) or args['debug']:
|
||||
f.write("template<>\n")
|
||||
f.write("struct output_streamer<"+struct_name+"&> {\n")
|
||||
f.write(" inline static std::ostream& put(std::ostream& out, "+struct_name+"& v)\n")
|
||||
f.write("{\n")
|
||||
flag=1;
|
||||
if flag==1 and key == 'field_type':
|
||||
field_type = match.group('field_type')
|
||||
if field_type == "":
|
||||
field_type="notype"
|
||||
if flag==1 and key == 'field_rawtype':
|
||||
field_rawtype = match.group('field_rawtype')
|
||||
if field_rawtype == "":
|
||||
field_rawtype="notype"
|
||||
if flag==1 and key == 'array_size_val':
|
||||
array_size_val = match.group('array_size_val')
|
||||
tmp_str=tmp_str.replace(field_type,field_type+"["+array_size_val+"]")
|
||||
f.write(tmp_str+"\n")
|
||||
tmp_str=""
|
||||
if flag==1 and key == 'field_name' and "union" not in field_type:
|
||||
if tmp_str!="":
|
||||
f.write(tmp_str+"\n")
|
||||
tmp_str=""
|
||||
field_name = match.group('field_name')
|
||||
if field_name == "":
|
||||
field_name="noname"
|
||||
if field_name!="" and field_type=="":
|
||||
field_type=field_rawtype
|
||||
if (field_name!="noname" and field_type!="notype" and not re.search("void",field_type)) or args['debug'] :
|
||||
tmp_str=" roctracer::kfd_support::output_streamer<"+field_type+">::put(out,v."+field_name+")"+";";
|
||||
tmp_str=tmp_str.replace('<::', '<')
|
||||
line = file_object.readline()
|
||||
if tmp_str!="":
|
||||
f.write(tmp_str+"\n")
|
||||
tmp_str=""
|
||||
if flag==1:
|
||||
for c in cppHeader.classes:
|
||||
if "union" in c:
|
||||
continue
|
||||
f.write("\ntemplate<>\n")
|
||||
f.write("struct output_streamer<"+c+"&> {\n")
|
||||
f.write(" inline static std::ostream& put(std::ostream& out, "+c+"& v)\n")
|
||||
f.write("{\n")
|
||||
process_struct(f,c,cppHeader,"")
|
||||
f.write(" return out;\n")
|
||||
f.write("}\n")
|
||||
f.write("};\n")
|
||||
|
||||
FOOTER = \
|
||||
'// end ostream ops for KFD \n'
|
||||
'// end ostream ops for KFD \n'
|
||||
FOOTER += '};};\n' + \
|
||||
'\n' + \
|
||||
'#endif // INC_KFD_OSTREAM_OPS_H_\n' + \
|
||||
@@ -178,29 +168,11 @@ def parse_file(infilepath,outfilepath):
|
||||
'#endif // INC_BASIC_OSTREAM_OPS_H_\n' + \
|
||||
' \n'
|
||||
f.write(FOOTER)
|
||||
f.close()
|
||||
print ("File "+outfilepath+" has been generated.")
|
||||
|
||||
return
|
||||
|
||||
def gen_cppheader_lut(infilepath):
|
||||
try:
|
||||
cppHeader = CppHeaderParser.CppHeader(infilepath)
|
||||
except CppHeaderParser.CppParseError as e:
|
||||
print(e)
|
||||
sys.exit(1)
|
||||
|
||||
f= open("cppheader_lut.txt","w+")
|
||||
for c in cppHeader.classes:
|
||||
f.write("typedef %s\n"%(c))
|
||||
for l in range(len(cppHeader.classes[c]["properties"]["public"])):
|
||||
for key in cppHeader.classes[c]["properties"]["public"][l].keys():
|
||||
f.write(" name[%s]=%s\n"%(key,cppHeader.classes[c]["properties"]["public"][l][key]))
|
||||
f.close()
|
||||
return
|
||||
|
||||
parser = argparse.ArgumentParser(description='genOstreamOps.py: generates ostream operators for all typedefs in provided input file.')
|
||||
parser.add_argument('-debug','--debug', help='Debug option for features not supported by CppHeaderParser', action='store_true')
|
||||
requiredNamed=parser.add_argument_group('Required arguments')
|
||||
requiredNamed.add_argument('-in','--in', help='Header file to be parsed', required=True)
|
||||
requiredNamed.add_argument('-out','--out', help='Output file with ostream operators', required=True)
|
||||
@@ -208,6 +180,5 @@ requiredNamed.add_argument('-out','--out', help='Output file with ostream operat
|
||||
args = vars(parser.parse_args())
|
||||
|
||||
if __name__ == '__main__':
|
||||
gen_cppheader_lut(args['in'])
|
||||
parse_file("cppheader_lut.txt",args['out'])
|
||||
gen_cppheader(args['in'],args['out'])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user