diff --git a/projects/roctracer/script/gen_ostream_ops.py b/projects/roctracer/script/gen_ostream_ops.py index eaf39277ab..693111547c 100644 --- a/projects/roctracer/script/gen_ostream_ops.py +++ b/projects/roctracer/script/gen_ostream_ops.py @@ -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 {\n' + \ ' inline static std::ostream& put(std::ostream& out, bool v) { out << std::hex << ""; return out; }\n' + \ '};\n' + \ -'template<>\n' + \ +'\ntemplate<>\n' + \ 'struct output_streamer {\n' + \ ' inline static std::ostream& put(std::ostream& out, uint8_t v) { out << std::hex << ""; return out; }\n' + \ '};\n' + \ -'template<>\n' + \ +'\ntemplate<>\n' + \ 'struct output_streamer {\n' + \ ' inline static std::ostream& put(std::ostream& out, uint16_t v) { out << std::hex << ""; return out; }\n' + \ '};\n' + \ -'template<>\n' + \ +'\ntemplate<>\n' + \ 'struct output_streamer {\n' + \ ' inline static std::ostream& put(std::ostream& out, uint32_t v) { out << std::hex << ""; return out; }\n' + \ '};\n' + \ -'template<>\n' + \ +'\ntemplate<>\n' + \ 'struct output_streamer {\n' + \ ' inline static std::ostream& put(std::ostream& out, uint64_t v) { out << std::hex << ""; return out; }\n' + \ '};\n' + \ '\n' + \ -'template<>\n' + \ +'\ntemplate<>\n' + \ 'struct output_streamer {\n' + \ ' inline static std::ostream& put(std::ostream& out, bool* v) { out << std::hex << ""; return out; }\n' + \ '};\n' + \ -'template<>\n' + \ +'\ntemplate<>\n' + \ 'struct output_streamer {\n' + \ ' inline static std::ostream& put(std::ostream& out, uint8_t* v) { out << std::hex << ""; return out; }\n' + \ '};\n' + \ -'template<>\n' + \ +'\ntemplate<>\n' + \ 'struct output_streamer {\n' + \ ' inline static std::ostream& put(std::ostream& out, uint16_t* v) { out << std::hex << ""; return out; }\n' + \ '};\n' + \ -'template<>\n' + \ +'\ntemplate<>\n' + \ 'struct output_streamer {\n' + \ ' inline static std::ostream& put(std::ostream& out, uint32_t* v) { out << std::hex << ""; return out; }\n' + \ '};\n' + \ -'template<>\n' + \ +'\ntemplate<>\n' + \ 'struct output_streamer {\n' + \ ' inline static std::ostream& put(std::ostream& out, uint64_t* v) { out << std::hex << ""; return out; }\n' + \ '};\n' + \ '\n' -rx_dict = { - 'struct_name': re.compile(r'typedef (?P.*)\n'), - 'field_type': re.compile(r'\s+name\[type\]=(?P.*)\n'), - 'field_rawtype': re.compile(r'\s+name\[raw_type\]=(?P.*)\n'), - 'field_name': re.compile(r'\s+name\[name\]=(?P.*)\n'), - 'array_size_val': re.compile(r'\s+name\[array_size\]=(?P.*)\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'])