Remove everything related to CTF sequences and variants
[deliverable/barectf.git] / barectf / tsdl182gen.py
1 # The MIT License (MIT)
2 #
3 # Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
4 #
5 # Permission is hereby granted, free of charge, to any person obtaining a copy
6 # of this software and associated documentation files (the "Software"), to deal
7 # in the Software without restriction, including without limitation the rights
8 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 # copies of the Software, and to permit persons to whom the Software is
10 # furnished to do so, subject to the following conditions:
11 #
12 # The above copyright notice and this permission notice shall be included in
13 # all copies or substantial portions of the Software.
14 #
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 # THE SOFTWARE.
22
23 from barectf import metadata
24 from barectf import codegen
25 import datetime
26 import barectf
27
28
29 _bo_to_string_map = {
30 metadata.ByteOrder.LE: 'le',
31 metadata.ByteOrder.BE: 'be',
32 }
33
34
35 _encoding_to_string_map = {
36 metadata.Encoding.NONE: 'none',
37 metadata.Encoding.ASCII: 'ASCII',
38 metadata.Encoding.UTF8: 'UTF8',
39 }
40
41
42 def _bo_to_string(bo):
43 return _bo_to_string_map[bo]
44
45
46 def _encoding_to_string(encoding):
47 return _encoding_to_string_map[encoding]
48
49
50 def _bool_to_string(b):
51 return 'true' if b else 'false'
52
53
54 def _gen_integer(t, cg):
55 cg.add_line('integer {')
56 cg.indent()
57 cg.add_line('size = {};'.format(t.size))
58 cg.add_line('align = {};'.format(t.align))
59 cg.add_line('signed = {};'.format(_bool_to_string(t.signed)))
60 cg.add_line('byte_order = {};'.format(_bo_to_string(t.byte_order)))
61 cg.add_line('base = {};'.format(t.base))
62 cg.add_line('encoding = {};'.format(_encoding_to_string(t.encoding)))
63
64 if t.property_mappings:
65 clock_name = t.property_mappings[0].object.name
66 cg.add_line('map = clock.{}.value;'.format(clock_name))
67
68 cg.unindent()
69 cg.add_line('}')
70
71
72 def _gen_float(t, cg):
73 cg.add_line('floating_point {')
74 cg.indent()
75 cg.add_line('exp_dig = {};'.format(t.exp_size))
76 cg.add_line('mant_dig = {};'.format(t.mant_size))
77 cg.add_line('align = {};'.format(t.align))
78 cg.add_line('byte_order = {};'.format(_bo_to_string(t.byte_order)))
79 cg.unindent()
80 cg.add_line('}')
81
82
83 def _gen_enum(t, cg):
84 cg.add_line('enum : ')
85 cg.add_glue()
86 _gen_type(t.value_type, cg)
87 cg.append_to_last_line(' {')
88 cg.indent()
89
90 for label, (mn, mx) in t.members.items():
91 if mn == mx:
92 rg = str(mn)
93 else:
94 rg = '{} ... {}'.format(mn, mx)
95
96 line = '"{}" = {},'.format(label, rg)
97 cg.add_line(line)
98
99 cg.unindent()
100 cg.add_line('}')
101
102
103 def _gen_string(t, cg):
104 cg.add_line('string {')
105 cg.indent()
106 cg.add_line('encoding = {};'.format(_encoding_to_string(t.encoding)))
107 cg.unindent()
108 cg.add_line('}')
109
110
111 def _find_deepest_array_element_type(t):
112 if type(t) is metadata.Array:
113 return _find_deepest_array_element_type(t.element_type)
114
115 return t
116
117
118 def _fill_array_lengths(t, lengths):
119 if type(t) is metadata.Array:
120 lengths.append(t.length)
121 _fill_array_lengths(t.element_type, lengths)
122
123
124 def _gen_struct_entry(name, t, cg):
125 real_t = _find_deepest_array_element_type(t)
126 _gen_type(real_t, cg)
127 cg.append_to_last_line(' {}'.format(name))
128
129 # array
130 lengths = []
131 _fill_array_lengths(t, lengths)
132
133 if lengths:
134 for length in reversed(lengths):
135 cg.append_to_last_line('[{}]'.format(length))
136
137 cg.append_to_last_line(';')
138
139
140 def _gen_struct(t, cg):
141 cg.add_line('struct {')
142 cg.indent()
143
144 for field_name, field_type in t.fields.items():
145 _gen_struct_entry(field_name, field_type, cg)
146
147 cg.unindent()
148
149 if not t.fields:
150 cg.add_glue()
151
152 cg.add_line('}} align({})'.format(t.min_align))
153
154
155 _type_to_gen_type_func = {
156 metadata.Integer: _gen_integer,
157 metadata.FloatingPoint: _gen_float,
158 metadata.Enum: _gen_enum,
159 metadata.String: _gen_string,
160 metadata.Struct: _gen_struct,
161 }
162
163
164 def _gen_type(t, cg):
165 _type_to_gen_type_func[type(t)](t, cg)
166
167
168 def _gen_entity(name, t, cg):
169 cg.add_line('{} := '.format(name))
170 cg.add_glue()
171 _gen_type(t, cg)
172 cg.append_to_last_line(';')
173
174
175 def _gen_start_block(name, cg):
176 cg.add_line('{} {{'.format(name))
177 cg.indent()
178
179
180 def _gen_end_block(cg):
181 cg.unindent()
182 cg.add_line('};')
183 cg.add_empty_line()
184
185
186 def _gen_trace_block(meta, cg):
187 trace = meta.trace
188
189 _gen_start_block('trace', cg)
190 cg.add_line('major = 1;')
191 cg.add_line('minor = 8;')
192 line = 'byte_order = {};'.format(_bo_to_string(trace.byte_order))
193 cg.add_line(line)
194
195 if trace.uuid is not None:
196 line = 'uuid = "{}";'.format(trace.uuid)
197 cg.add_line(line)
198
199 if trace.packet_header_type is not None:
200 _gen_entity('packet.header', trace.packet_header_type, cg)
201
202 _gen_end_block(cg)
203
204
205 def _escape_literal_string(s):
206 esc = s.replace('\\', '\\\\')
207 esc = esc.replace('\n', '\\n')
208 esc = esc.replace('\r', '\\r')
209 esc = esc.replace('\t', '\\t')
210 esc = esc.replace('"', '\\"')
211
212 return esc
213
214
215 def _gen_env_block(meta, cg):
216 env = meta.env
217
218 if not env:
219 return
220
221 _gen_start_block('env', cg)
222
223 for name, value in env.items():
224 if type(value) is int:
225 value_string = str(value)
226 else:
227 value_string = '"{}"'.format(_escape_literal_string(value))
228
229 cg.add_line('{} = {};'.format(name, value_string))
230
231 _gen_end_block(cg)
232
233
234 def _gen_clock_block(clock, cg):
235 _gen_start_block('clock', cg)
236 cg.add_line('name = {};'.format(clock.name))
237
238 if clock.description is not None:
239 desc = _escape_literal_string(clock.description)
240 cg.add_line('description = "{}";'.format(desc))
241
242 if clock.uuid is not None:
243 cg.add_line('uuid = "{}";'.format(clock.uuid))
244
245 cg.add_line('freq = {};'.format(clock.freq))
246 cg.add_line('offset_s = {};'.format(clock.offset_seconds))
247 cg.add_line('offset = {};'.format(clock.offset_cycles))
248 cg.add_line('precision = {};'.format(clock.error_cycles))
249 cg.add_line('absolute = {};'.format(_bool_to_string(clock.absolute)))
250 _gen_end_block(cg)
251
252
253 def _gen_clock_blocks(meta, cg):
254 clocks = meta.clocks
255
256 for clock in clocks.values():
257 _gen_clock_block(clock, cg)
258
259
260 def _gen_stream_block(meta, stream, cg):
261 cg.add_cc_line(stream.name.replace('/', ''))
262 _gen_start_block('stream', cg)
263
264 if meta.trace.packet_header_type is not None:
265 if 'stream_id' in meta.trace.packet_header_type.fields:
266 cg.add_line('id = {};'.format(stream.id))
267
268 if stream.packet_context_type is not None:
269 _gen_entity('packet.context', stream.packet_context_type, cg)
270
271 if stream.event_header_type is not None:
272 _gen_entity('event.header', stream.event_header_type, cg)
273
274 if stream.event_context_type is not None:
275 _gen_entity('event.context', stream.event_context_type, cg)
276
277 _gen_end_block(cg)
278
279
280 def _gen_event_block(meta, stream, ev, cg):
281 _gen_start_block('event', cg)
282 cg.add_line('name = "{}";'.format(ev.name))
283 cg.add_line('id = {};'.format(ev.id))
284
285 if meta.trace.packet_header_type is not None:
286 if 'stream_id' in meta.trace.packet_header_type.fields:
287 cg.add_line('stream_id = {};'.format(stream.id))
288
289 cg.append_cc_to_last_line(stream.name.replace('/', ''))
290
291 if ev.log_level is not None:
292 add_fmt = ''
293
294 if ev.log_level.name is not None:
295 name = ev.log_level.name.replace('*/', '')
296 add_fmt = ' /* {} */'.format(name)
297
298 fmt = 'loglevel = {};' + add_fmt
299 cg.add_line(fmt.format(ev.log_level.value))
300
301 if ev.context_type is not None:
302 _gen_entity('context', ev.context_type, cg)
303
304 if ev.payload_type is not None:
305 _gen_entity('fields', ev.payload_type, cg)
306 else:
307 fake_payload = metadata.Struct()
308 fake_payload.min_align = 8
309 _gen_entity('fields', fake_payload, cg)
310
311 _gen_end_block(cg)
312
313
314 def _gen_streams_events_blocks(meta, cg):
315 for stream in meta.streams.values():
316 _gen_stream_block(meta, stream, cg)
317
318 for ev in stream.events.values():
319 _gen_event_block(meta, stream, ev, cg)
320
321
322 def from_metadata(meta):
323 cg = codegen.CodeGenerator('\t')
324
325 # version/magic
326 cg.add_line('/* CTF 1.8 */')
327 cg.add_empty_line()
328 cg.add_line('''/*
329 * The MIT License (MIT)
330 *
331 * Copyright (c) 2015-2016 Philippe Proulx <pproulx@efficios.com>
332 *
333 * Permission is hereby granted, free of charge, to any person obtaining a copy
334 * of this software and associated documentation files (the "Software"), to deal
335 * in the Software without restriction, including without limitation the rights
336 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
337 * copies of the Software, and to permit persons to whom the Software is
338 * furnished to do so, subject to the following conditions:
339 *
340 * The above copyright notice and this permission notice shall be included in
341 * all copies or substantial portions of the Software.
342 *
343 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
344 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
345 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
346 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
347 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
348 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
349 * THE SOFTWARE.
350 *
351 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
352 *''')
353 v = barectf.__version__
354 line = ' * The following TSDL code was generated by barectf v{}'.format(v)
355 cg.add_line(line)
356 now = datetime.datetime.now()
357 line = ' * on {}.'.format(now)
358 cg.add_line(line)
359 cg.add_line(' *')
360 cg.add_line(' * For more details, see <http://barectf.org>.')
361 cg.add_line(' */')
362 cg.add_empty_line()
363
364 # trace block
365 _gen_trace_block(meta, cg)
366
367 # environment
368 _gen_env_block(meta, cg)
369
370 # clocks
371 _gen_clock_blocks(meta, cg)
372
373 # streams and contained events
374 _gen_streams_events_blocks(meta, cg)
375
376 return cg.code
This page took 0.043271 seconds and 5 git commands to generate.