Commit | Line | Data |
---|---|---|
89086b3e JD |
1 | #!/usr/bin/env python3 |
2 | # | |
3 | # The MIT License (MIT) | |
4 | # | |
5 | # Copyright (C) 2016 - Julien Desfossez <jdesfossez@efficios.com> | |
6 | # | |
7 | # Permission is hereby granted, free of charge, to any person obtaining a copy | |
8 | # of this software and associated documentation files (the "Software"), to deal | |
9 | # in the Software without restriction, including without limitation the rights | |
10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
11 | # copies of the Software, and to permit persons to whom the Software is | |
12 | # furnished to do so, subject to the following conditions: | |
13 | # | |
14 | # The above copyright notice and this permission notice shall be included in | |
15 | # all copies or substantial portions of the Software. | |
16 | # | |
17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
23 | # SOFTWARE. | |
24 | ||
25 | # Helper tool to generate CTFWriter code from the metadata of an existing | |
26 | # trace. | |
27 | # It used to add code in TraceTest.py. | |
28 | # Only the basic types are supported, a warning is generated if a field cannot | |
29 | # be generated so it is easy to look manually at the metadata and fix it. | |
30 | ||
31 | import sys | |
32 | import argparse | |
33 | ||
34 | from babeltrace import TraceCollection, CTFScope, CTFTypeId | |
35 | ||
36 | ||
37 | def get_definition_type(field, event): | |
38 | if field.type == CTFTypeId.INTEGER: | |
39 | signed = '' | |
40 | if field.signedness == 0: | |
41 | signed = 'u' | |
42 | length = field.length | |
43 | print(' self.%s.add_field(self.%sint%s_type, "_%s")' % | |
44 | (event.name, signed, length, field.name)) | |
45 | elif field.type == CTFTypeId.ARRAY: | |
46 | print(' self.%s.add_field(self.array%s_type, "_%s")' % | |
47 | (event.name, field.length, field.name)) | |
48 | elif field.type == CTFTypeId.STRING: | |
49 | print(' self.%s.add_field(self.string_type, "_%s")' % | |
50 | (event.name, field.name)) | |
51 | else: | |
52 | print(' # FIXME %s.%s: Unhandled type %d' % (event.name, | |
53 | field.name, | |
54 | field.type)) | |
55 | ||
56 | ||
57 | def gen_define(event): | |
58 | fields = [] | |
59 | print(' def define_%s(self):' % (event.name)) | |
60 | print(' self.%s = CTFWriter.EventClass("%s")' % | |
61 | (event.name, event.name)) | |
62 | for field in event.fields: | |
63 | if field.scope == CTFScope.EVENT_FIELDS: | |
64 | fname = field.name | |
65 | fields.append(fname) | |
66 | get_definition_type(field, event) | |
67 | print(' self.add_event(self.%s)' % event.name) | |
68 | print('') | |
69 | return fields | |
70 | ||
71 | ||
72 | def gen_write(event, fields): | |
73 | f_list = None | |
74 | for f in fields: | |
75 | if f_list is None: | |
76 | f_list = f | |
77 | else: | |
78 | f_list = f_list + ", %s" % (f) | |
79 | print(' def write_%s(self, time_ms, cpu_id, %s):' % (event.name, | |
80 | f_list)) | |
81 | print(' event = CTFWriter.Event(self.%s)' % (event.name)) | |
82 | print(' self.clock.time = time_ms * 1000000') | |
83 | print(' self.set_int(event.payload("_cpu_id"), cpu_id)') | |
84 | for field in event.fields: | |
85 | if field.scope == CTFScope.EVENT_FIELDS: | |
86 | fname = field.name | |
87 | if field.type == CTFTypeId.INTEGER: | |
88 | print(' self.set_int(event.payload("_%s"), %s)' % | |
89 | (fname, fname)) | |
90 | elif field.type == CTFTypeId.ARRAY: | |
91 | print(' self.set_char_array(event.payload("_%s"), ' | |
92 | '%s)' % (fname, fname)) | |
93 | elif field.type == CTFTypeId.STRING: | |
94 | print(' self.set_string(event.payload("_%s"), %s)' % | |
95 | (fname, fname)) | |
96 | else: | |
97 | print(' # FIXME %s.%s: Unhandled type %d' % | |
98 | (event.name, field.name, field.type)) | |
99 | print(' self.stream.append_event(event)') | |
100 | print(' self.stream.flush()') | |
101 | print('') | |
102 | ||
103 | ||
104 | def gen_parser(handle, args): | |
105 | for h in handle.values(): | |
106 | for event in h.events: | |
107 | fields = gen_define(event) | |
108 | gen_write(event, fields) | |
109 | ||
110 | ||
111 | if __name__ == "__main__": | |
112 | parser = argparse.ArgumentParser(description='CTFWriter code generator') | |
113 | parser.add_argument('path', metavar="<path/to/trace>", help='Trace path') | |
114 | args = parser.parse_args() | |
115 | ||
116 | traces = TraceCollection() | |
117 | handle = traces.add_traces_recursive(args.path, "ctf") | |
118 | if handle is None: | |
119 | sys.exit(1) | |
120 | ||
121 | gen_parser(handle, args) | |
122 | ||
123 | for h in handle.values(): | |
124 | traces.remove_trace(h) |