1 # The MIT License (MIT)
3 # Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
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:
12 # The above copyright notice and this permission notice shall be included in
13 # all copies or substantial portions of the Software.
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
23 from barectf
import metadata
24 from barectf
import codegen
30 metadata
.ByteOrder
.LE
: 'le',
31 metadata
.ByteOrder
.BE
: 'be',
35 _encoding_to_string_map
= {
36 metadata
.Encoding
.NONE
: 'none',
37 metadata
.Encoding
.ASCII
: 'ASCII',
38 metadata
.Encoding
.UTF8
: 'UTF8',
42 def _bo_to_string(bo
):
43 return _bo_to_string_map
[bo
]
46 def _encoding_to_string(encoding
):
47 return _encoding_to_string_map
[encoding
]
50 def _bool_to_string(b
):
51 return 'true' if b
else 'false'
54 def _gen_integer(t
, cg
):
55 cg
.add_line('integer {')
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
)))
64 if t
.property_mappings
:
65 clock_name
= t
.property_mappings
[0].object.name
66 cg
.add_line('map = clock.{}.value;'.format(clock_name
))
72 def _gen_float(t
, cg
):
73 cg
.add_line('floating_point {')
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
)))
84 cg
.add_line('enum : ')
86 _gen_type(t
.value_type
, cg
)
87 cg
.append_to_last_line(' {')
90 for label
, (mn
, mx
) in t
.members
.items():
94 rg
= '{} ... {}'.format(mn
, mx
)
96 line
= '"{}" = {},'.format(label
, rg
)
103 def _gen_string(t
, cg
):
104 cg
.add_line('string {')
106 cg
.add_line('encoding = {};'.format(_encoding_to_string(t
.encoding
)))
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
)
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
)
124 def _gen_struct_variant_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
))
131 _fill_array_lengths(t
, lengths
)
134 for length
in reversed(lengths
):
135 cg
.append_to_last_line('[{}]'.format(length
))
137 cg
.append_to_last_line(';')
140 def _gen_struct(t
, cg
):
141 cg
.add_line('struct {')
144 for field_name
, field_type
in t
.fields
.items():
145 _gen_struct_variant_entry(field_name
, field_type
, cg
)
152 cg
.add_line('}} align({})'.format(t
.min_align
))
155 def _gen_variant(t
, cg
):
156 cg
.add_line('variant <{}> {{'.format(t
.tag
))
159 for type_name
, type_type
in t
.types
.items():
160 _gen_struct_variant_entry(type_name
, type_type
, cg
)
170 _type_to_gen_type_func
= {
171 metadata
.Integer
: _gen_integer
,
172 metadata
.FloatingPoint
: _gen_float
,
173 metadata
.Enum
: _gen_enum
,
174 metadata
.String
: _gen_string
,
175 metadata
.Struct
: _gen_struct
,
176 metadata
.Variant
: _gen_variant
,
180 def _gen_type(t
, cg
):
181 _type_to_gen_type_func
[type(t
)](t
, cg
)
184 def _gen_entity(name
, t
, cg
):
185 cg
.add_line('{} := '.format(name
))
188 cg
.append_to_last_line(';')
191 def _gen_start_block(name
, cg
):
192 cg
.add_line('{} {{'.format(name
))
196 def _gen_end_block(cg
):
202 def _gen_trace_block(meta
, cg
):
205 _gen_start_block('trace', cg
)
206 cg
.add_line('major = 1;')
207 cg
.add_line('minor = 8;')
208 line
= 'byte_order = {};'.format(_bo_to_string(trace
.byte_order
))
211 if trace
.uuid
is not None:
212 line
= 'uuid = "{}";'.format(trace
.uuid
)
215 if trace
.packet_header_type
is not None:
216 _gen_entity('packet.header', trace
.packet_header_type
, cg
)
221 def _escape_literal_string(s
):
222 esc
= s
.replace('\\', '\\\\')
223 esc
= esc
.replace('\n', '\\n')
224 esc
= esc
.replace('\r', '\\r')
225 esc
= esc
.replace('\t', '\\t')
226 esc
= esc
.replace('"', '\\"')
231 def _gen_env_block(meta
, cg
):
237 _gen_start_block('env', cg
)
239 for name
, value
in env
.items():
240 if type(value
) is int:
241 value_string
= str(value
)
243 value_string
= '"{}"'.format(_escape_literal_string(value
))
245 cg
.add_line('{} = {};'.format(name
, value_string
))
250 def _gen_clock_block(clock
, cg
):
251 _gen_start_block('clock', cg
)
252 cg
.add_line('name = {};'.format(clock
.name
))
254 if clock
.description
is not None:
255 desc
= _escape_literal_string(clock
.description
)
256 cg
.add_line('description = "{}";'.format(desc
))
258 if clock
.uuid
is not None:
259 cg
.add_line('uuid = "{}";'.format(clock
.uuid
))
261 cg
.add_line('freq = {};'.format(clock
.freq
))
262 cg
.add_line('offset_s = {};'.format(clock
.offset_seconds
))
263 cg
.add_line('offset = {};'.format(clock
.offset_cycles
))
264 cg
.add_line('precision = {};'.format(clock
.error_cycles
))
265 cg
.add_line('absolute = {};'.format(_bool_to_string(clock
.absolute
)))
269 def _gen_clock_blocks(meta
, cg
):
272 for clock
in clocks
.values():
273 _gen_clock_block(clock
, cg
)
276 def _gen_stream_block(meta
, stream
, cg
):
277 cg
.add_cc_line(stream
.name
.replace('/', ''))
278 _gen_start_block('stream', cg
)
280 if meta
.trace
.packet_header_type
is not None:
281 if 'stream_id' in meta
.trace
.packet_header_type
.fields
:
282 cg
.add_line('id = {};'.format(stream
.id))
284 if stream
.packet_context_type
is not None:
285 _gen_entity('packet.context', stream
.packet_context_type
, cg
)
287 if stream
.event_header_type
is not None:
288 _gen_entity('event.header', stream
.event_header_type
, cg
)
290 if stream
.event_context_type
is not None:
291 _gen_entity('event.context', stream
.event_context_type
, cg
)
296 def _gen_event_block(meta
, stream
, ev
, cg
):
297 _gen_start_block('event', cg
)
298 cg
.add_line('name = "{}";'.format(ev
.name
))
299 cg
.add_line('id = {};'.format(ev
.id))
301 if meta
.trace
.packet_header_type
is not None:
302 if 'stream_id' in meta
.trace
.packet_header_type
.fields
:
303 cg
.add_line('stream_id = {};'.format(stream
.id))
305 cg
.append_cc_to_last_line(stream
.name
.replace('/', ''))
307 if ev
.log_level
is not None:
310 if ev
.log_level
.name
is not None:
311 name
= ev
.log_level
.name
.replace('*/', '')
312 add_fmt
= ' /* {} */'.format(name
)
314 fmt
= 'loglevel = {};' + add_fmt
315 cg
.add_line(fmt
.format(ev
.log_level
.value
))
317 if ev
.context_type
is not None:
318 _gen_entity('context', ev
.context_type
, cg
)
320 if ev
.payload_type
is not None:
321 _gen_entity('fields', ev
.payload_type
, cg
)
323 fake_payload
= metadata
.Struct()
324 fake_payload
.min_align
= 8
325 _gen_entity('fields', fake_payload
, cg
)
330 def _gen_streams_events_blocks(meta
, cg
):
331 for stream
in meta
.streams
.values():
332 _gen_stream_block(meta
, stream
, cg
)
334 for ev
in stream
.events
.values():
335 _gen_event_block(meta
, stream
, ev
, cg
)
338 def from_metadata(meta
):
339 cg
= codegen
.CodeGenerator('\t')
342 cg
.add_line('/* CTF 1.8 */')
345 v
= barectf
.__version
__
346 line
= ' * The following TSDL code was generated by barectf v{}'.format(v
)
348 now
= datetime
.datetime
.now()
349 line
= ' * on {}.'.format(now
)
352 cg
.add_line(' * For more details, see <https://github.com/efficios/barectf>.')
357 _gen_trace_block(meta
, cg
)
360 _gen_env_block(meta
, cg
)
363 _gen_clock_blocks(meta
, cg
)
365 # streams and contained events
366 _gen_streams_events_blocks(meta
, cg
)
This page took 0.042984 seconds and 4 git commands to generate.