• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#   Copyright (c) 2022 Huawei Device Co., Ltd.
4#   Licensed under the Apache License, Version 2.0 (the "License");
5#   you may not use this file except in compliance with the License.
6#   You may obtain a copy of the License at
7#
8#       http://www.apache.org/licenses/LICENSE-2.0
9#
10#   Unless required by applicable law or agreed to in writing, software
11#   distributed under the License is distributed on an "AS IS" BASIS,
12#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13#   See the License for the specific language governing permissions and
14#   limitations under the License.
15
16def get_type_def(file):
17    offset = file.tell()
18    file.seek(0, 2)
19    file_size = file.tell()
20    file.seek(offset, 0)
21    startline = ""
22    type_def_lines = []
23    while file.tell() < file_size:
24        startline = file.readline()
25        index = startline.find("struct sys")
26        if index == 0:
27            type_def_lines.append(startline)
28            while True:
29                line = file.readline()
30                line = line.strip()
31                type_def_lines.append(line)
32                if line == "};":
33                    break
34            break
35    return type_def_lines
36
37
38def get_args_name(type_def_lines):
39    startline = type_def_lines[0]
40    splitted_startline = startline.split(' ')
41    type_name = splitted_startline[1]
42    return type_name[4:-2]
43
44
45def get_converter_name(type_def_lines):
46    startline = type_def_lines[0]
47    splitted_startline = startline.split(' ')
48    type_name = splitted_startline[1]
49    splitted_type_name = type_name.split('_')
50    splitted_type_name = splitted_type_name[1:-1]
51    converter_name = ""
52    for item in splitted_type_name:
53        converter_name = "{}{}".format(converter_name, item.capitalize()
54    converter_name = "{}Converter".format(converter_name)
55    return converter_name
56
57
58BAD_MEMBER = "bad nr"
59VOID_MEMBER = "void"
60
61
62def get_argmember_name(type_def_lines, nr_member):
63    max_nr_members = len(type_def_lines) - 2
64    max_nr_members_limit = 4
65    if max_nr_members > max_nr_members_limit:
66        max_nr_members = max_nr_members_limit
67    if nr_member < 1:
68        return BAD_MEMBER
69    if max_nr_members < nr_member and nr_member <= max_nr_members_limit:
70        return VOID_MEMBER
71    if max_nr_members_limit < nr_member:
72        return BAD_MEMBER
73    member_line = type_def_lines[nr_member]
74    splitted_member_line = member_line.split(' ')
75    member_name = splitted_member_line[-1]
76    member_name = member_name[:-1]
77    return member_name
78
79converter_table = []
80
81
82def generate_converter(type_def_lines):
83    fn_name = get_converter_name(type_def_lines)
84    fn_decl = "static int {}(__u64* args, const struct fstrace_start_event_t* start_event)\n".format(fn_name)
85    max_nr_args = 4
86    expressions = ""
87    for nr in range(max_nr_args):
88        expression_line = ""
89        arg_name = get_args_name(type_def_lines)
90        member_name = get_argmember_name(type_def_lines, nr + 1)
91        if member_name == BAD_MEMBER:
92            break
93        if member_name == VOID_MEMBER:
94            expression_line = "    args[{}] = 0xFFFFFFFFFFFFFFFF;\n".format(str(nr))
95        else:
96            expression_line = "    args[{}] = (__u64) start_event->{}.{};\n".format(str(nr), arg_name, member_name)
97        expressions.join(expression_line)
98    converter = "{}{\n{}    return 0;\n}\n\n".format(fn_decl, expressions)
99    converter_table.append(("&" + fn_name))
100    return converter
101
102CONVERTER_FILE_HEAD = '''
103#include "type_headers.h"
104
105
106'''
107
108
109def output_converter_code(fstrace_types_file, converters_file):
110    nr_converters = 1
111    with open(converters_file, 'w') as outf:
112        outf.write(CONVERTER_FILE_HEAD)
113        with open(fstrace_types_file, 'r') as inf:
114            while True:
115                type_def_lines = get_type_def(inf)
116                if len(type_def_lines) == 0:
117                    break
118                converter = generate_converter(type_def_lines)
119                outf.write(converter)
120                nr_converters = nr_converters + 1
121        converter_table_code = (
122            "using ConverterType = int (*) (__u64*, const struct fstrace_start_event_t *);\n")
123        converter_table_code = "{}ConverterType g_argsConverterTable[{}] = {\n    nullptr".format(converter_table_code, str(nr_converters))
124        for fn_ptr in converter_table:
125            converter_table_code = "{},\n    {}".format(converter_table_code, fn_ptr)
126        converter_table_code = "%s\n};\n" % (converter_table_code)
127        outf.write(converter_table_code)
128
129if __name__ == '__main__':
130    output_converter_code("../include/fstrace_types.h", "../src/fstrace_args_converter.cpp")
131