def get_type_def(file):
offset = file.tell()
file.seek(0, 2)
file_size = file.tell()
file.seek(offset, 0)
startline = ""
type_def_lines = []
while file.tell() < file_size:
startline = file.readline()
index = startline.find("struct sys")
if index == 0:
type_def_lines.append(startline)
while True:
line = file.readline()
line = line.strip()
type_def_lines.append(line)
if line == "};":
break
break
return type_def_lines
def get_args_name(type_def_lines):
startline = type_def_lines[0]
splitted_startline = startline.split(' ')
type_name = splitted_startline[1]
return type_name[4:-2]
def get_converter_name(type_def_lines):
startline = type_def_lines[0]
splitted_startline = startline.split(' ')
type_name = splitted_startline[1]
splitted_type_name = type_name.split('_')
splitted_type_name = splitted_type_name[1:-1]
converter_name = ""
for item in splitted_type_name:
converter_name = "{}{}".format(converter_name, item.capitalize()
converter_name = "{}Converter".format(converter_name)
return converter_name
BAD_MEMBER = "bad nr"
VOID_MEMBER = "void"
def get_argmember_name(type_def_lines, nr_member):
max_nr_members = len(type_def_lines) - 2
max_nr_members_limit = 4
if max_nr_members > max_nr_members_limit:
max_nr_members = max_nr_members_limit
if nr_member < 1:
return BAD_MEMBER
if max_nr_members < nr_member and nr_member <= max_nr_members_limit:
return VOID_MEMBER
if max_nr_members_limit < nr_member:
return BAD_MEMBER
member_line = type_def_lines[nr_member]
splitted_member_line = member_line.split(' ')
member_name = splitted_member_line[-1]
member_name = member_name[:-1]
return member_name
converter_table = []
def generate_converter(type_def_lines):
fn_name = get_converter_name(type_def_lines)
fn_decl = "static int {}(__u64* args, const struct fstrace_start_event_t* start_event)\n".format(fn_name)
max_nr_args = 4
expressions = ""
for nr in range(max_nr_args):
expression_line = ""
arg_name = get_args_name(type_def_lines)
member_name = get_argmember_name(type_def_lines, nr + 1)
if member_name == BAD_MEMBER:
break
if member_name == VOID_MEMBER:
expression_line = " args[{}] = 0xFFFFFFFFFFFFFFFF;\n".format(str(nr))
else:
expression_line = " args[{}] = (__u64) start_event->{}.{};\n".format(str(nr), arg_name, member_name)
expressions.join(expression_line)
converter = "{}{\n{} return 0;\n}\n\n".format(fn_decl, expressions)
converter_table.append(("&" + fn_name))
return converter
CONVERTER_FILE_HEAD = '''
#include "type_headers.h"
'''
def output_converter_code(fstrace_types_file, converters_file):
nr_converters = 1
with open(converters_file, 'w') as outf:
outf.write(CONVERTER_FILE_HEAD)
with open(fstrace_types_file, 'r') as inf:
while True:
type_def_lines = get_type_def(inf)
if len(type_def_lines) == 0:
break
converter = generate_converter(type_def_lines)
outf.write(converter)
nr_converters = nr_converters + 1
converter_table_code = (
"using ConverterType = int (*) (__u64*, const struct fstrace_start_event_t *);\n")
converter_table_code = "{}ConverterType g_argsConverterTable[{}] = {\n nullptr".format(converter_table_code, str(nr_converters))
for fn_ptr in converter_table:
converter_table_code = "{},\n {}".format(converter_table_code, fn_ptr)
converter_table_code = "%s\n};\n" % (converter_table_code)
outf.write(converter_table_code)
if __name__ == '__main__':
output_converter_code("../include/fstrace_types.h", "../src/fstrace_args_converter.cpp")