106f6ba60Sopenharmony_ci#!/usr/bin/env python
206f6ba60Sopenharmony_ci# -*- coding: utf-8 -*-
306f6ba60Sopenharmony_ci#   Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
406f6ba60Sopenharmony_ci#   Licensed under the Apache License, Version 2.0 (the "License");
506f6ba60Sopenharmony_ci#   you may not use this file except in compliance with the License.
606f6ba60Sopenharmony_ci#   You may obtain a copy of the License at
706f6ba60Sopenharmony_ci#
806f6ba60Sopenharmony_ci#       http://www.apache.org/licenses/LICENSE-2.0
906f6ba60Sopenharmony_ci#
1006f6ba60Sopenharmony_ci#   Unless required by applicable law or agreed to in writing, software
1106f6ba60Sopenharmony_ci#   distributed under the License is distributed on an "AS IS" BASIS,
1206f6ba60Sopenharmony_ci#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1306f6ba60Sopenharmony_ci#   See the License for the specific language governing permissions and
1406f6ba60Sopenharmony_ci#   limitations under the License.
1506f6ba60Sopenharmony_ci
1606f6ba60Sopenharmony_cidef get_type_def(file):
1706f6ba60Sopenharmony_ci    offset = file.tell()
1806f6ba60Sopenharmony_ci    file.seek(0, 2)
1906f6ba60Sopenharmony_ci    file_size = file.tell()
2006f6ba60Sopenharmony_ci    file.seek(offset, 0)
2106f6ba60Sopenharmony_ci    startline = ""
2206f6ba60Sopenharmony_ci    type_def_lines = []
2306f6ba60Sopenharmony_ci    while file.tell() < file_size:
2406f6ba60Sopenharmony_ci        startline = file.readline()
2506f6ba60Sopenharmony_ci        index = startline.find("struct sys")
2606f6ba60Sopenharmony_ci        if index == 0:
2706f6ba60Sopenharmony_ci            type_def_lines.append(startline)
2806f6ba60Sopenharmony_ci            while True:
2906f6ba60Sopenharmony_ci                line = file.readline()
3006f6ba60Sopenharmony_ci                line = line.strip()
3106f6ba60Sopenharmony_ci                type_def_lines.append(line)
3206f6ba60Sopenharmony_ci                if line == "};":
3306f6ba60Sopenharmony_ci                    break
3406f6ba60Sopenharmony_ci            break
3506f6ba60Sopenharmony_ci    return type_def_lines
3606f6ba60Sopenharmony_ci
3706f6ba60Sopenharmony_ci
3806f6ba60Sopenharmony_cidef get_args_name(type_def_lines):
3906f6ba60Sopenharmony_ci    startline = type_def_lines[0]
4006f6ba60Sopenharmony_ci    splitted_startline = startline.split(' ')
4106f6ba60Sopenharmony_ci    type_name = splitted_startline[1]
4206f6ba60Sopenharmony_ci    return type_name[4:-2]
4306f6ba60Sopenharmony_ci
4406f6ba60Sopenharmony_ci
4506f6ba60Sopenharmony_cidef get_converter_name(type_def_lines):
4606f6ba60Sopenharmony_ci    startline = type_def_lines[0]
4706f6ba60Sopenharmony_ci    splitted_startline = startline.split(' ')
4806f6ba60Sopenharmony_ci    type_name = splitted_startline[1]
4906f6ba60Sopenharmony_ci    splitted_type_name = type_name.split('_')
5006f6ba60Sopenharmony_ci    splitted_type_name = splitted_type_name[1:-1]
5106f6ba60Sopenharmony_ci    converter_name = ""
5206f6ba60Sopenharmony_ci    for item in splitted_type_name:
5306f6ba60Sopenharmony_ci        converter_name = "{}{}".format(converter_name, item.capitalize()
5406f6ba60Sopenharmony_ci    converter_name = "{}Converter".format(converter_name)
5506f6ba60Sopenharmony_ci    return converter_name
5606f6ba60Sopenharmony_ci
5706f6ba60Sopenharmony_ci
5806f6ba60Sopenharmony_ciBAD_MEMBER = "bad nr"
5906f6ba60Sopenharmony_ciVOID_MEMBER = "void"
6006f6ba60Sopenharmony_ci
6106f6ba60Sopenharmony_ci
6206f6ba60Sopenharmony_cidef get_argmember_name(type_def_lines, nr_member):
6306f6ba60Sopenharmony_ci    max_nr_members = len(type_def_lines) - 2
6406f6ba60Sopenharmony_ci    max_nr_members_limit = 4
6506f6ba60Sopenharmony_ci    if max_nr_members > max_nr_members_limit:
6606f6ba60Sopenharmony_ci        max_nr_members = max_nr_members_limit
6706f6ba60Sopenharmony_ci    if nr_member < 1:
6806f6ba60Sopenharmony_ci        return BAD_MEMBER
6906f6ba60Sopenharmony_ci    if max_nr_members < nr_member and nr_member <= max_nr_members_limit:
7006f6ba60Sopenharmony_ci        return VOID_MEMBER
7106f6ba60Sopenharmony_ci    if max_nr_members_limit < nr_member:
7206f6ba60Sopenharmony_ci        return BAD_MEMBER
7306f6ba60Sopenharmony_ci    member_line = type_def_lines[nr_member]
7406f6ba60Sopenharmony_ci    splitted_member_line = member_line.split(' ')
7506f6ba60Sopenharmony_ci    member_name = splitted_member_line[-1]
7606f6ba60Sopenharmony_ci    member_name = member_name[:-1]
7706f6ba60Sopenharmony_ci    return member_name
7806f6ba60Sopenharmony_ci
7906f6ba60Sopenharmony_ciconverter_table = []
8006f6ba60Sopenharmony_ci
8106f6ba60Sopenharmony_ci
8206f6ba60Sopenharmony_cidef generate_converter(type_def_lines):
8306f6ba60Sopenharmony_ci    fn_name = get_converter_name(type_def_lines)
8406f6ba60Sopenharmony_ci    fn_decl = "static int {}(__u64* args, const struct fstrace_start_event_t* start_event)\n".format(fn_name)
8506f6ba60Sopenharmony_ci    max_nr_args = 4
8606f6ba60Sopenharmony_ci    expressions = ""
8706f6ba60Sopenharmony_ci    for nr in range(max_nr_args):
8806f6ba60Sopenharmony_ci        expression_line = ""
8906f6ba60Sopenharmony_ci        arg_name = get_args_name(type_def_lines)
9006f6ba60Sopenharmony_ci        member_name = get_argmember_name(type_def_lines, nr + 1)
9106f6ba60Sopenharmony_ci        if member_name == BAD_MEMBER:
9206f6ba60Sopenharmony_ci            break
9306f6ba60Sopenharmony_ci        if member_name == VOID_MEMBER:
9406f6ba60Sopenharmony_ci            expression_line = "    args[{}] = 0xFFFFFFFFFFFFFFFF;\n".format(str(nr))
9506f6ba60Sopenharmony_ci        else:
9606f6ba60Sopenharmony_ci            expression_line = "    args[{}] = (__u64) start_event->{}.{};\n".format(str(nr), arg_name, member_name)
9706f6ba60Sopenharmony_ci        expressions.join(expression_line)
9806f6ba60Sopenharmony_ci    converter = "{}{\n{}    return 0;\n}\n\n".format(fn_decl, expressions)
9906f6ba60Sopenharmony_ci    converter_table.append(("&" + fn_name))
10006f6ba60Sopenharmony_ci    return converter
10106f6ba60Sopenharmony_ci
10206f6ba60Sopenharmony_ciCONVERTER_FILE_HEAD = '''
10306f6ba60Sopenharmony_ci#include "type_headers.h"
10406f6ba60Sopenharmony_ci
10506f6ba60Sopenharmony_ci
10606f6ba60Sopenharmony_ci'''
10706f6ba60Sopenharmony_ci
10806f6ba60Sopenharmony_ci
10906f6ba60Sopenharmony_cidef output_converter_code(fstrace_types_file, converters_file):
11006f6ba60Sopenharmony_ci    nr_converters = 1
11106f6ba60Sopenharmony_ci    with open(converters_file, 'w') as outf:
11206f6ba60Sopenharmony_ci        outf.write(CONVERTER_FILE_HEAD)
11306f6ba60Sopenharmony_ci        with open(fstrace_types_file, 'r') as inf:
11406f6ba60Sopenharmony_ci            while True:
11506f6ba60Sopenharmony_ci                type_def_lines = get_type_def(inf)
11606f6ba60Sopenharmony_ci                if len(type_def_lines) == 0:
11706f6ba60Sopenharmony_ci                    break
11806f6ba60Sopenharmony_ci                converter = generate_converter(type_def_lines)
11906f6ba60Sopenharmony_ci                outf.write(converter)
12006f6ba60Sopenharmony_ci                nr_converters = nr_converters + 1
12106f6ba60Sopenharmony_ci        converter_table_code = (
12206f6ba60Sopenharmony_ci            "using ConverterType = int (*) (__u64*, const struct fstrace_start_event_t *);\n")
12306f6ba60Sopenharmony_ci        converter_table_code = "{}ConverterType g_argsConverterTable[{}] = {\n    nullptr".format(converter_table_code, str(nr_converters))
12406f6ba60Sopenharmony_ci        for fn_ptr in converter_table:
12506f6ba60Sopenharmony_ci            converter_table_code = "{},\n    {}".format(converter_table_code, fn_ptr)
12606f6ba60Sopenharmony_ci        converter_table_code = "%s\n};\n" % (converter_table_code)
12706f6ba60Sopenharmony_ci        outf.write(converter_table_code)
12806f6ba60Sopenharmony_ci
12906f6ba60Sopenharmony_ciif __name__ == '__main__':
13006f6ba60Sopenharmony_ci    output_converter_code("../include/fstrace_types.h", "../src/fstrace_args_converter.cpp")
131