Commit | Line | Data |
---|---|---|
44c440bc | 1 | /* |
0235b0db | 2 | * SPDX-License-Identifier: MIT |
44c440bc | 3 | * |
0235b0db | 4 | * Copyright 2018 Philippe Proulx <pproulx@efficios.com> |
44c440bc PP |
5 | */ |
6 | ||
44c440bc PP |
7 | #include <stdint.h> |
8 | #include <string.h> | |
c802cacb SM |
9 | |
10 | #include <babeltrace2/babeltrace.h> | |
11 | ||
12 | #include "common/assert.h" | |
44c440bc | 13 | |
087cd0f5 | 14 | #include "ctf-meta-visitors.hpp" |
44c440bc | 15 | |
a1501ac9 SM |
16 | namespace ctf { |
17 | ||
18 | struct MetaTranslateCtx | |
4164020e SM |
19 | { |
20 | bt_self_component *self_comp; | |
21 | bt_trace_class *ir_tc; | |
22 | bt_stream_class *ir_sc; | |
23 | struct ctf_trace_class *tc; | |
24 | struct ctf_stream_class *sc; | |
25 | struct ctf_event_class *ec; | |
26 | enum ctf_scope scope; | |
83ebb7f1 PP |
27 | }; |
28 | ||
a1501ac9 SM |
29 | } /* namespace ctf */ |
30 | ||
31 | static inline bt_field_class *ctf_field_class_to_ir(ctf::MetaTranslateCtx *ctx, | |
32 | struct ctf_field_class *fc); | |
44c440bc | 33 | |
4164020e SM |
34 | static inline void ctf_field_class_int_set_props(struct ctf_field_class_int *fc, |
35 | bt_field_class *ir_fc) | |
44c440bc | 36 | { |
4164020e SM |
37 | bt_field_class_integer_set_field_value_range(ir_fc, fc->base.size); |
38 | bt_field_class_integer_set_preferred_display_base(ir_fc, fc->disp_base); | |
44c440bc PP |
39 | } |
40 | ||
a1501ac9 | 41 | static inline bt_field_class *ctf_field_class_int_to_ir(ctf::MetaTranslateCtx *ctx, |
4164020e | 42 | struct ctf_field_class_int *fc) |
44c440bc | 43 | { |
4164020e | 44 | bt_field_class *ir_fc; |
44c440bc | 45 | |
4164020e SM |
46 | if (fc->is_signed) { |
47 | ir_fc = bt_field_class_integer_signed_create(ctx->ir_tc); | |
48 | } else { | |
49 | ir_fc = bt_field_class_integer_unsigned_create(ctx->ir_tc); | |
50 | } | |
44c440bc | 51 | |
4164020e SM |
52 | BT_ASSERT(ir_fc); |
53 | ctf_field_class_int_set_props(fc, ir_fc); | |
54 | return ir_fc; | |
44c440bc PP |
55 | } |
56 | ||
a1501ac9 | 57 | static inline bt_field_class *ctf_field_class_enum_to_ir(ctf::MetaTranslateCtx *ctx, |
4164020e | 58 | struct ctf_field_class_enum *fc) |
44c440bc | 59 | { |
4164020e SM |
60 | int ret; |
61 | bt_field_class *ir_fc; | |
62 | uint64_t i; | |
63 | ||
64 | if (fc->base.is_signed) { | |
65 | ir_fc = bt_field_class_enumeration_signed_create(ctx->ir_tc); | |
66 | } else { | |
67 | ir_fc = bt_field_class_enumeration_unsigned_create(ctx->ir_tc); | |
68 | } | |
69 | ||
70 | BT_ASSERT(ir_fc); | |
71 | ctf_field_class_int_set_props(&fc->base, ir_fc); | |
72 | ||
73 | for (i = 0; i < fc->mappings->len; i++) { | |
74 | struct ctf_field_class_enum_mapping *mapping = | |
75 | ctf_field_class_enum_borrow_mapping_by_index(fc, i); | |
76 | bt_integer_range_set_signed *range_set_signed = NULL; | |
77 | bt_integer_range_set_unsigned *range_set_unsigned = NULL; | |
78 | uint64_t range_i; | |
79 | ||
80 | if (fc->base.is_signed) { | |
81 | range_set_signed = bt_integer_range_set_signed_create(); | |
82 | BT_ASSERT(range_set_signed); | |
83 | } else { | |
84 | range_set_unsigned = bt_integer_range_set_unsigned_create(); | |
85 | BT_ASSERT(range_set_unsigned); | |
86 | } | |
87 | ||
88 | for (range_i = 0; range_i < mapping->ranges->len; range_i++) { | |
89 | struct ctf_range *range = | |
90 | ctf_field_class_enum_mapping_borrow_range_by_index(mapping, range_i); | |
91 | ||
92 | if (fc->base.is_signed) { | |
93 | ret = bt_integer_range_set_signed_add_range(range_set_signed, range->lower.i, | |
94 | range->upper.i); | |
95 | } else { | |
96 | ret = bt_integer_range_set_unsigned_add_range(range_set_unsigned, range->lower.u, | |
97 | range->upper.u); | |
98 | } | |
99 | ||
100 | BT_ASSERT(ret == 0); | |
101 | } | |
102 | ||
103 | if (fc->base.is_signed) { | |
104 | ret = bt_field_class_enumeration_signed_add_mapping(ir_fc, mapping->label->str, | |
105 | range_set_signed); | |
106 | BT_INTEGER_RANGE_SET_SIGNED_PUT_REF_AND_RESET(range_set_signed); | |
107 | } else { | |
108 | ret = bt_field_class_enumeration_unsigned_add_mapping(ir_fc, mapping->label->str, | |
109 | range_set_unsigned); | |
110 | BT_INTEGER_RANGE_SET_UNSIGNED_PUT_REF_AND_RESET(range_set_unsigned); | |
111 | } | |
112 | ||
113 | BT_ASSERT(ret == 0); | |
114 | } | |
115 | ||
116 | return ir_fc; | |
44c440bc PP |
117 | } |
118 | ||
a1501ac9 | 119 | static inline bt_field_class *ctf_field_class_float_to_ir(ctf::MetaTranslateCtx *ctx, |
4164020e | 120 | struct ctf_field_class_float *fc) |
44c440bc | 121 | { |
4164020e | 122 | bt_field_class *ir_fc; |
44c440bc | 123 | |
4164020e SM |
124 | if (fc->base.size == 32) { |
125 | ir_fc = bt_field_class_real_single_precision_create(ctx->ir_tc); | |
126 | } else { | |
127 | ir_fc = bt_field_class_real_double_precision_create(ctx->ir_tc); | |
128 | } | |
129 | BT_ASSERT(ir_fc); | |
44c440bc | 130 | |
4164020e | 131 | return ir_fc; |
44c440bc PP |
132 | } |
133 | ||
a1501ac9 | 134 | static inline bt_field_class *ctf_field_class_string_to_ir(ctf::MetaTranslateCtx *ctx) |
44c440bc | 135 | { |
4164020e | 136 | bt_field_class *ir_fc = bt_field_class_string_create(ctx->ir_tc); |
44c440bc | 137 | |
4164020e SM |
138 | BT_ASSERT(ir_fc); |
139 | return ir_fc; | |
44c440bc PP |
140 | } |
141 | ||
a1501ac9 | 142 | static inline void translate_struct_field_class_members(ctf::MetaTranslateCtx *ctx, |
4164020e | 143 | struct ctf_field_class_struct *fc, |
5bcd9f04 | 144 | bt_field_class *ir_fc, bool, |
ecd7492f | 145 | struct ctf_field_class_struct *) |
44c440bc | 146 | { |
4164020e SM |
147 | uint64_t i; |
148 | int ret; | |
149 | ||
150 | for (i = 0; i < fc->members->len; i++) { | |
151 | struct ctf_named_field_class *named_fc = | |
152 | ctf_field_class_struct_borrow_member_by_index(fc, i); | |
153 | bt_field_class *member_ir_fc; | |
154 | const char *name = named_fc->name->str; | |
155 | ||
156 | if (!named_fc->fc->in_ir) { | |
157 | continue; | |
158 | } | |
159 | ||
160 | member_ir_fc = ctf_field_class_to_ir(ctx, named_fc->fc); | |
161 | BT_ASSERT(member_ir_fc); | |
162 | ret = bt_field_class_structure_append_member(ir_fc, name, member_ir_fc); | |
163 | BT_ASSERT(ret == 0); | |
164 | bt_field_class_put_ref(member_ir_fc); | |
165 | } | |
83ebb7f1 | 166 | } |
44c440bc | 167 | |
a1501ac9 | 168 | static inline bt_field_class *ctf_field_class_struct_to_ir(ctf::MetaTranslateCtx *ctx, |
4164020e | 169 | struct ctf_field_class_struct *fc) |
83ebb7f1 | 170 | { |
4164020e | 171 | bt_field_class *ir_fc = bt_field_class_structure_create(ctx->ir_tc); |
83ebb7f1 | 172 | |
4164020e SM |
173 | BT_ASSERT(ir_fc); |
174 | translate_struct_field_class_members(ctx, fc, ir_fc, false, NULL); | |
175 | return ir_fc; | |
44c440bc PP |
176 | } |
177 | ||
a1501ac9 | 178 | static inline bt_field_class *borrow_ir_fc_from_field_path(ctf::MetaTranslateCtx *ctx, |
4164020e | 179 | struct ctf_field_path *field_path) |
44c440bc | 180 | { |
4164020e SM |
181 | bt_field_class *ir_fc = NULL; |
182 | struct ctf_field_class *fc = | |
183 | ctf_field_path_borrow_field_class(field_path, ctx->tc, ctx->sc, ctx->ec); | |
44c440bc | 184 | |
4164020e | 185 | BT_ASSERT(fc); |
44c440bc | 186 | |
4164020e SM |
187 | if (fc->in_ir) { |
188 | ir_fc = fc->ir_fc; | |
189 | } | |
44c440bc | 190 | |
4164020e | 191 | return ir_fc; |
44c440bc PP |
192 | } |
193 | ||
4164020e SM |
194 | static inline const bt_field_class_enumeration_mapping * |
195 | find_ir_enum_field_class_mapping_by_label(const bt_field_class *fc, const char *label, | |
196 | bool is_signed) | |
45c51519 | 197 | { |
4164020e SM |
198 | const bt_field_class_enumeration_mapping *mapping = NULL; |
199 | uint64_t i; | |
200 | ||
201 | for (i = 0; i < bt_field_class_enumeration_get_mapping_count(fc); i++) { | |
202 | const bt_field_class_enumeration_mapping *this_mapping; | |
203 | const bt_field_class_enumeration_signed_mapping *signed_this_mapping = NULL; | |
204 | const bt_field_class_enumeration_unsigned_mapping *unsigned_this_mapping = NULL; | |
205 | ||
206 | if (is_signed) { | |
207 | signed_this_mapping = | |
208 | bt_field_class_enumeration_signed_borrow_mapping_by_index_const(fc, i); | |
209 | BT_ASSERT(signed_this_mapping); | |
210 | this_mapping = | |
211 | bt_field_class_enumeration_signed_mapping_as_mapping_const(signed_this_mapping); | |
212 | } else { | |
213 | unsigned_this_mapping = | |
214 | bt_field_class_enumeration_unsigned_borrow_mapping_by_index_const(fc, i); | |
215 | BT_ASSERT(unsigned_this_mapping); | |
216 | this_mapping = | |
217 | bt_field_class_enumeration_unsigned_mapping_as_mapping_const(unsigned_this_mapping); | |
218 | } | |
219 | ||
220 | BT_ASSERT(this_mapping); | |
221 | ||
222 | if (strcmp(bt_field_class_enumeration_mapping_get_label(this_mapping), label) == 0) { | |
223 | mapping = this_mapping; | |
224 | goto end; | |
225 | } | |
226 | } | |
45c51519 PP |
227 | |
228 | end: | |
4164020e | 229 | return mapping; |
45c51519 PP |
230 | } |
231 | ||
a1501ac9 | 232 | static inline bt_field_class *ctf_field_class_variant_to_ir(ctf::MetaTranslateCtx *ctx, |
4164020e | 233 | struct ctf_field_class_variant *fc) |
44c440bc | 234 | { |
4164020e SM |
235 | int ret; |
236 | bt_field_class *ir_fc; | |
237 | uint64_t i; | |
238 | bt_field_class *ir_tag_fc = NULL; | |
239 | ||
240 | if (fc->tag_path.root != CTF_SCOPE_PACKET_HEADER && | |
241 | fc->tag_path.root != CTF_SCOPE_EVENT_HEADER) { | |
242 | ir_tag_fc = borrow_ir_fc_from_field_path(ctx, &fc->tag_path); | |
243 | BT_ASSERT(ir_tag_fc); | |
244 | } | |
245 | ||
246 | ir_fc = bt_field_class_variant_create(ctx->ir_tc, ir_tag_fc); | |
247 | BT_ASSERT(ir_fc); | |
248 | ||
249 | for (i = 0; i < fc->options->len; i++) { | |
250 | struct ctf_named_field_class *named_fc = | |
251 | ctf_field_class_variant_borrow_option_by_index(fc, i); | |
252 | bt_field_class *option_ir_fc; | |
253 | ||
254 | BT_ASSERT(named_fc->fc->in_ir); | |
255 | option_ir_fc = ctf_field_class_to_ir(ctx, named_fc->fc); | |
256 | BT_ASSERT(option_ir_fc); | |
257 | ||
258 | if (ir_tag_fc) { | |
259 | /* | |
260 | * At this point the trace IR selector | |
261 | * (enumeration) field class already exists if | |
262 | * the variant is tagged (`ir_tag_fc`). This one | |
263 | * already contains range sets for its mappings, | |
264 | * so we just reuse the same, finding them by | |
265 | * matching a variant field class's option's | |
266 | * _original_ name (with a leading underscore, | |
267 | * possibly) with a selector field class's | |
268 | * mapping name. | |
269 | */ | |
270 | if (fc->tag_fc->base.is_signed) { | |
271 | const bt_field_class_enumeration_signed_mapping *mapping = | |
272 | (bt_field_class_enumeration_signed_mapping *) | |
273 | find_ir_enum_field_class_mapping_by_label(ir_tag_fc, | |
274 | named_fc->orig_name->str, true); | |
275 | const bt_integer_range_set_signed *range_set; | |
276 | ||
277 | BT_ASSERT(mapping); | |
278 | range_set = bt_field_class_enumeration_signed_mapping_borrow_ranges_const(mapping); | |
279 | BT_ASSERT(range_set); | |
280 | ret = bt_field_class_variant_with_selector_field_integer_signed_append_option( | |
281 | ir_fc, named_fc->name->str, option_ir_fc, range_set); | |
282 | } else { | |
283 | const bt_field_class_enumeration_unsigned_mapping *mapping = | |
284 | (bt_field_class_enumeration_unsigned_mapping *) | |
285 | find_ir_enum_field_class_mapping_by_label(ir_tag_fc, | |
286 | named_fc->orig_name->str, false); | |
287 | const bt_integer_range_set_unsigned *range_set; | |
288 | ||
289 | BT_ASSERT(mapping); | |
290 | range_set = | |
291 | bt_field_class_enumeration_unsigned_mapping_borrow_ranges_const(mapping); | |
292 | BT_ASSERT(range_set); | |
293 | ret = bt_field_class_variant_with_selector_field_integer_unsigned_append_option( | |
294 | ir_fc, named_fc->name->str, option_ir_fc, range_set); | |
295 | } | |
296 | } else { | |
297 | ret = bt_field_class_variant_without_selector_append_option(ir_fc, named_fc->name->str, | |
298 | option_ir_fc); | |
299 | } | |
300 | ||
301 | BT_ASSERT(ret == 0); | |
302 | bt_field_class_put_ref(option_ir_fc); | |
303 | } | |
304 | ||
305 | return ir_fc; | |
44c440bc PP |
306 | } |
307 | ||
a1501ac9 | 308 | static inline bt_field_class *ctf_field_class_array_to_ir(ctf::MetaTranslateCtx *ctx, |
4164020e | 309 | struct ctf_field_class_array *fc) |
44c440bc | 310 | { |
4164020e SM |
311 | bt_field_class *ir_fc; |
312 | bt_field_class *elem_ir_fc; | |
313 | ||
314 | if (fc->base.is_text) { | |
315 | ir_fc = bt_field_class_string_create(ctx->ir_tc); | |
316 | BT_ASSERT(ir_fc); | |
317 | goto end; | |
318 | } | |
319 | ||
320 | elem_ir_fc = ctf_field_class_to_ir(ctx, fc->base.elem_fc); | |
321 | BT_ASSERT(elem_ir_fc); | |
322 | ir_fc = bt_field_class_array_static_create(ctx->ir_tc, elem_ir_fc, fc->length); | |
323 | BT_ASSERT(ir_fc); | |
324 | bt_field_class_put_ref(elem_ir_fc); | |
44c440bc PP |
325 | |
326 | end: | |
4164020e | 327 | return ir_fc; |
44c440bc PP |
328 | } |
329 | ||
a1501ac9 | 330 | static inline bt_field_class *ctf_field_class_sequence_to_ir(ctf::MetaTranslateCtx *ctx, |
4164020e | 331 | struct ctf_field_class_sequence *fc) |
44c440bc | 332 | { |
4164020e SM |
333 | bt_field_class *ir_fc; |
334 | bt_field_class *elem_ir_fc; | |
335 | bt_field_class *length_fc = NULL; | |
336 | ||
337 | if (fc->base.is_text) { | |
338 | ir_fc = bt_field_class_string_create(ctx->ir_tc); | |
339 | BT_ASSERT(ir_fc); | |
340 | goto end; | |
341 | } | |
342 | ||
343 | elem_ir_fc = ctf_field_class_to_ir(ctx, fc->base.elem_fc); | |
344 | BT_ASSERT(elem_ir_fc); | |
345 | ||
346 | if (fc->length_path.root != CTF_SCOPE_PACKET_HEADER && | |
347 | fc->length_path.root != CTF_SCOPE_EVENT_HEADER) { | |
348 | length_fc = borrow_ir_fc_from_field_path(ctx, &fc->length_path); | |
349 | BT_ASSERT(length_fc); | |
350 | } | |
351 | ||
352 | ir_fc = bt_field_class_array_dynamic_create(ctx->ir_tc, elem_ir_fc, length_fc); | |
353 | BT_ASSERT(ir_fc); | |
354 | bt_field_class_put_ref(elem_ir_fc); | |
355 | BT_ASSERT(ir_fc); | |
1367bc7c | 356 | |
44c440bc | 357 | end: |
4164020e | 358 | return ir_fc; |
44c440bc PP |
359 | } |
360 | ||
a1501ac9 SM |
361 | static inline bt_field_class *ctf_field_class_to_ir(ctf::MetaTranslateCtx *ctx, |
362 | struct ctf_field_class *fc) | |
44c440bc | 363 | { |
4164020e SM |
364 | bt_field_class *ir_fc = NULL; |
365 | ||
366 | BT_ASSERT(fc); | |
367 | BT_ASSERT(fc->in_ir); | |
368 | ||
369 | switch (fc->type) { | |
370 | case CTF_FIELD_CLASS_TYPE_INT: | |
371 | ir_fc = ctf_field_class_int_to_ir(ctx, ctf_field_class_as_int(fc)); | |
372 | break; | |
373 | case CTF_FIELD_CLASS_TYPE_ENUM: | |
374 | ir_fc = ctf_field_class_enum_to_ir(ctx, ctf_field_class_as_enum(fc)); | |
375 | break; | |
376 | case CTF_FIELD_CLASS_TYPE_FLOAT: | |
377 | ir_fc = ctf_field_class_float_to_ir(ctx, ctf_field_class_as_float(fc)); | |
378 | break; | |
379 | case CTF_FIELD_CLASS_TYPE_STRING: | |
a1501ac9 | 380 | ir_fc = ctf_field_class_string_to_ir(ctx); |
4164020e SM |
381 | break; |
382 | case CTF_FIELD_CLASS_TYPE_STRUCT: | |
383 | ir_fc = ctf_field_class_struct_to_ir(ctx, ctf_field_class_as_struct(fc)); | |
384 | break; | |
385 | case CTF_FIELD_CLASS_TYPE_ARRAY: | |
386 | ir_fc = ctf_field_class_array_to_ir(ctx, ctf_field_class_as_array(fc)); | |
387 | break; | |
388 | case CTF_FIELD_CLASS_TYPE_SEQUENCE: | |
389 | ir_fc = ctf_field_class_sequence_to_ir(ctx, ctf_field_class_as_sequence(fc)); | |
390 | break; | |
391 | case CTF_FIELD_CLASS_TYPE_VARIANT: | |
392 | ir_fc = ctf_field_class_variant_to_ir(ctx, ctf_field_class_as_variant(fc)); | |
393 | break; | |
394 | default: | |
395 | bt_common_abort(); | |
396 | } | |
397 | ||
398 | fc->ir_fc = ir_fc; | |
399 | return ir_fc; | |
44c440bc PP |
400 | } |
401 | ||
4164020e SM |
402 | static inline bool |
403 | ctf_field_class_struct_has_immediate_member_in_ir(struct ctf_field_class_struct *fc) | |
44c440bc | 404 | { |
4164020e SM |
405 | uint64_t i; |
406 | bool has_immediate_member_in_ir = false; | |
407 | ||
408 | /* | |
409 | * If the structure field class has no members at all, then it | |
410 | * was an empty structure in the beginning, so leave it existing | |
411 | * and empty. | |
412 | */ | |
413 | if (fc->members->len == 0) { | |
414 | has_immediate_member_in_ir = true; | |
415 | goto end; | |
416 | } | |
417 | ||
418 | for (i = 0; i < fc->members->len; i++) { | |
419 | struct ctf_named_field_class *named_fc = | |
420 | ctf_field_class_struct_borrow_member_by_index(fc, i); | |
421 | ||
422 | if (named_fc->fc->in_ir) { | |
423 | has_immediate_member_in_ir = true; | |
424 | goto end; | |
425 | } | |
426 | } | |
44c440bc PP |
427 | |
428 | end: | |
4164020e | 429 | return has_immediate_member_in_ir; |
44c440bc PP |
430 | } |
431 | ||
a1501ac9 | 432 | static inline bt_field_class *scope_ctf_field_class_to_ir(ctf::MetaTranslateCtx *ctx) |
44c440bc | 433 | { |
4164020e SM |
434 | bt_field_class *ir_fc = NULL; |
435 | struct ctf_field_class *fc = NULL; | |
436 | ||
437 | switch (ctx->scope) { | |
438 | case CTF_SCOPE_PACKET_CONTEXT: | |
439 | fc = ctx->sc->packet_context_fc; | |
440 | break; | |
441 | case CTF_SCOPE_EVENT_COMMON_CONTEXT: | |
442 | fc = ctx->sc->event_common_context_fc; | |
443 | break; | |
444 | case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT: | |
445 | fc = ctx->ec->spec_context_fc; | |
446 | break; | |
447 | case CTF_SCOPE_EVENT_PAYLOAD: | |
448 | fc = ctx->ec->payload_fc; | |
449 | break; | |
450 | default: | |
451 | bt_common_abort(); | |
452 | } | |
453 | ||
454 | if (fc && ctf_field_class_struct_has_immediate_member_in_ir(ctf_field_class_as_struct(fc))) { | |
455 | ir_fc = ctf_field_class_to_ir(ctx, fc); | |
456 | } | |
457 | ||
458 | return ir_fc; | |
44c440bc PP |
459 | } |
460 | ||
a1501ac9 | 461 | static inline void ctf_event_class_to_ir(ctf::MetaTranslateCtx *ctx) |
44c440bc | 462 | { |
4164020e SM |
463 | int ret; |
464 | bt_event_class *ir_ec = NULL; | |
465 | bt_field_class *ir_fc; | |
466 | ||
467 | BT_ASSERT(ctx->ec); | |
468 | ||
469 | if (ctx->ec->is_translated) { | |
470 | ir_ec = bt_stream_class_borrow_event_class_by_id(ctx->ir_sc, ctx->ec->id); | |
471 | BT_ASSERT(ir_ec); | |
472 | goto end; | |
473 | } | |
474 | ||
475 | ir_ec = bt_event_class_create_with_id(ctx->ir_sc, ctx->ec->id); | |
476 | BT_ASSERT(ir_ec); | |
477 | bt_event_class_put_ref(ir_ec); | |
478 | ctx->scope = CTF_SCOPE_EVENT_SPECIFIC_CONTEXT; | |
479 | ir_fc = scope_ctf_field_class_to_ir(ctx); | |
480 | if (ir_fc) { | |
481 | ret = bt_event_class_set_specific_context_field_class(ir_ec, ir_fc); | |
482 | BT_ASSERT(ret == 0); | |
483 | bt_field_class_put_ref(ir_fc); | |
484 | } | |
485 | ||
486 | ctx->scope = CTF_SCOPE_EVENT_PAYLOAD; | |
487 | ir_fc = scope_ctf_field_class_to_ir(ctx); | |
488 | if (ir_fc) { | |
489 | ret = bt_event_class_set_payload_field_class(ir_ec, ir_fc); | |
490 | BT_ASSERT(ret == 0); | |
491 | bt_field_class_put_ref(ir_fc); | |
492 | } | |
493 | ||
494 | if (ctx->ec->name->len > 0) { | |
495 | ret = bt_event_class_set_name(ir_ec, ctx->ec->name->str); | |
496 | BT_ASSERT(ret == 0); | |
497 | } | |
498 | ||
499 | if (ctx->ec->emf_uri->len > 0) { | |
500 | ret = bt_event_class_set_emf_uri(ir_ec, ctx->ec->emf_uri->str); | |
501 | BT_ASSERT(ret == 0); | |
502 | } | |
503 | ||
504 | if (ctx->ec->is_log_level_set) { | |
505 | bt_event_class_set_log_level(ir_ec, ctx->ec->log_level); | |
506 | } | |
507 | ||
508 | ctx->ec->is_translated = true; | |
509 | ctx->ec->ir_ec = ir_ec; | |
44c440bc PP |
510 | |
511 | end: | |
4164020e | 512 | return; |
44c440bc PP |
513 | } |
514 | ||
a1501ac9 | 515 | static inline void ctf_stream_class_to_ir(ctf::MetaTranslateCtx *ctx) |
44c440bc | 516 | { |
4164020e SM |
517 | int ret; |
518 | bt_field_class *ir_fc; | |
519 | ||
520 | BT_ASSERT(ctx->sc); | |
521 | ||
522 | if (ctx->sc->is_translated) { | |
523 | ctx->ir_sc = bt_trace_class_borrow_stream_class_by_id(ctx->ir_tc, ctx->sc->id); | |
524 | BT_ASSERT(ctx->ir_sc); | |
525 | goto end; | |
526 | } | |
527 | ||
528 | ctx->ir_sc = bt_stream_class_create_with_id(ctx->ir_tc, ctx->sc->id); | |
529 | BT_ASSERT(ctx->ir_sc); | |
530 | bt_stream_class_put_ref(ctx->ir_sc); | |
531 | ||
532 | if (ctx->sc->default_clock_class) { | |
533 | BT_ASSERT(ctx->sc->default_clock_class->ir_cc); | |
534 | ret = bt_stream_class_set_default_clock_class(ctx->ir_sc, | |
535 | ctx->sc->default_clock_class->ir_cc); | |
536 | BT_ASSERT(ret == 0); | |
537 | } | |
538 | ||
539 | bt_stream_class_set_supports_packets(ctx->ir_sc, BT_TRUE, ctx->sc->packets_have_ts_begin, | |
540 | ctx->sc->packets_have_ts_end); | |
541 | bt_stream_class_set_supports_discarded_events(ctx->ir_sc, ctx->sc->has_discarded_events, | |
542 | ctx->sc->discarded_events_have_default_cs); | |
543 | bt_stream_class_set_supports_discarded_packets(ctx->ir_sc, ctx->sc->has_discarded_packets, | |
544 | ctx->sc->discarded_packets_have_default_cs); | |
545 | ctx->scope = CTF_SCOPE_PACKET_CONTEXT; | |
546 | ir_fc = scope_ctf_field_class_to_ir(ctx); | |
547 | if (ir_fc) { | |
548 | ret = bt_stream_class_set_packet_context_field_class(ctx->ir_sc, ir_fc); | |
549 | BT_ASSERT(ret == 0); | |
550 | bt_field_class_put_ref(ir_fc); | |
551 | } | |
552 | ||
553 | ctx->scope = CTF_SCOPE_EVENT_COMMON_CONTEXT; | |
554 | ir_fc = scope_ctf_field_class_to_ir(ctx); | |
555 | if (ir_fc) { | |
556 | ret = bt_stream_class_set_event_common_context_field_class(ctx->ir_sc, ir_fc); | |
557 | BT_ASSERT(ret == 0); | |
558 | bt_field_class_put_ref(ir_fc); | |
559 | } | |
560 | ||
561 | bt_stream_class_set_assigns_automatic_event_class_id(ctx->ir_sc, BT_FALSE); | |
562 | bt_stream_class_set_assigns_automatic_stream_id(ctx->ir_sc, BT_FALSE); | |
563 | ||
564 | ctx->sc->is_translated = true; | |
565 | ctx->sc->ir_sc = ctx->ir_sc; | |
44c440bc PP |
566 | |
567 | end: | |
4164020e | 568 | return; |
44c440bc PP |
569 | } |
570 | ||
4164020e | 571 | static inline void ctf_clock_class_to_ir(bt_clock_class *ir_cc, struct ctf_clock_class *cc) |
0f2d58c9 | 572 | { |
4164020e | 573 | int ret; |
0f2d58c9 | 574 | |
4164020e SM |
575 | if (strlen(cc->name->str) > 0) { |
576 | ret = bt_clock_class_set_name(ir_cc, cc->name->str); | |
577 | BT_ASSERT(ret == 0); | |
578 | } | |
0f2d58c9 | 579 | |
4164020e SM |
580 | if (strlen(cc->description->str) > 0) { |
581 | ret = bt_clock_class_set_description(ir_cc, cc->description->str); | |
582 | BT_ASSERT(ret == 0); | |
583 | } | |
0f2d58c9 | 584 | |
4164020e SM |
585 | bt_clock_class_set_frequency(ir_cc, cc->frequency); |
586 | bt_clock_class_set_precision(ir_cc, cc->precision); | |
587 | bt_clock_class_set_offset(ir_cc, cc->offset_seconds, cc->offset_cycles); | |
0f2d58c9 | 588 | |
4164020e SM |
589 | if (cc->has_uuid) { |
590 | bt_clock_class_set_uuid(ir_cc, cc->uuid); | |
591 | } | |
0f2d58c9 | 592 | |
4164020e | 593 | bt_clock_class_set_origin_is_unix_epoch(ir_cc, cc->is_absolute); |
0f2d58c9 PP |
594 | } |
595 | ||
a1501ac9 | 596 | static inline int ctf_trace_class_to_ir(ctf::MetaTranslateCtx *ctx) |
44c440bc | 597 | { |
4164020e SM |
598 | int ret = 0; |
599 | uint64_t i; | |
44c440bc | 600 | |
4164020e SM |
601 | BT_ASSERT(ctx->tc); |
602 | BT_ASSERT(ctx->ir_tc); | |
44c440bc | 603 | |
4164020e SM |
604 | if (ctx->tc->is_translated) { |
605 | goto end; | |
606 | } | |
44c440bc | 607 | |
4164020e SM |
608 | for (i = 0; i < ctx->tc->clock_classes->len; i++) { |
609 | ctf_clock_class *cc = (ctf_clock_class *) ctx->tc->clock_classes->pdata[i]; | |
0f2d58c9 | 610 | |
4164020e SM |
611 | cc->ir_cc = bt_clock_class_create(ctx->self_comp); |
612 | ctf_clock_class_to_ir(cc->ir_cc, cc); | |
613 | } | |
0f2d58c9 | 614 | |
4164020e SM |
615 | bt_trace_class_set_assigns_automatic_stream_class_id(ctx->ir_tc, BT_FALSE); |
616 | ctx->tc->is_translated = true; | |
617 | ctx->tc->ir_tc = ctx->ir_tc; | |
44c440bc PP |
618 | |
619 | end: | |
4164020e | 620 | return ret; |
44c440bc PP |
621 | } |
622 | ||
4164020e SM |
623 | int ctf_trace_class_translate(bt_self_component *self_comp, bt_trace_class *ir_tc, |
624 | struct ctf_trace_class *tc) | |
44c440bc | 625 | { |
4164020e SM |
626 | int ret = 0; |
627 | uint64_t i; | |
a1501ac9 | 628 | ctf::MetaTranslateCtx ctx = {}; |
44c440bc | 629 | |
4164020e SM |
630 | ctx.self_comp = self_comp; |
631 | ctx.tc = tc; | |
632 | ctx.ir_tc = ir_tc; | |
633 | ret = ctf_trace_class_to_ir(&ctx); | |
634 | if (ret) { | |
635 | goto end; | |
636 | } | |
44c440bc | 637 | |
4164020e SM |
638 | for (i = 0; i < tc->stream_classes->len; i++) { |
639 | uint64_t j; | |
640 | ctx.sc = (ctf_stream_class *) tc->stream_classes->pdata[i]; | |
44c440bc | 641 | |
4164020e | 642 | ctf_stream_class_to_ir(&ctx); |
44c440bc | 643 | |
4164020e SM |
644 | for (j = 0; j < ctx.sc->event_classes->len; j++) { |
645 | ctx.ec = (ctf_event_class *) ctx.sc->event_classes->pdata[j]; | |
44c440bc | 646 | |
4164020e SM |
647 | ctf_event_class_to_ir(&ctx); |
648 | ctx.ec = NULL; | |
649 | } | |
83ebb7f1 | 650 | |
4164020e SM |
651 | ctx.sc = NULL; |
652 | } | |
44c440bc PP |
653 | |
654 | end: | |
4164020e | 655 | return ret; |
44c440bc | 656 | } |