2 * Copyright 2018 - Philippe Proulx <pproulx@efficios.com>
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
15 #define BT_LOG_TAG "PLUGIN-CTF-METADATA-META-TRANSLATE"
18 #include <babeltrace/babeltrace.h>
19 #include <babeltrace/babeltrace-internal.h>
20 #include <babeltrace/assert-internal.h>
26 #include "ctf-meta-visitors.h"
29 bt_field_class
*ctf_field_class_to_ir(bt_trace_class
*ir_tc
,
30 struct ctf_field_class
*fc
,
31 struct ctf_trace_class
*tc
,
32 struct ctf_stream_class
*sc
,
33 struct ctf_event_class
*ec
);
36 void ctf_field_class_int_set_props(struct ctf_field_class_int
*fc
,
37 bt_field_class
*ir_fc
)
39 bt_field_class_integer_set_field_value_range(ir_fc
,
41 bt_field_class_integer_set_preferred_display_base(ir_fc
,
46 bt_field_class
*ctf_field_class_int_to_ir(bt_trace_class
*ir_tc
,
47 struct ctf_field_class_int
*fc
)
49 bt_field_class
*ir_fc
;
52 ir_fc
= bt_field_class_signed_integer_create(ir_tc
);
54 ir_fc
= bt_field_class_unsigned_integer_create(ir_tc
);
58 ctf_field_class_int_set_props(fc
, ir_fc
);
63 bt_field_class
*ctf_field_class_enum_to_ir(bt_trace_class
*ir_tc
,
64 struct ctf_field_class_enum
*fc
)
67 bt_field_class
*ir_fc
;
70 if (fc
->base
.is_signed
) {
71 ir_fc
= bt_field_class_signed_enumeration_create(ir_tc
);
73 ir_fc
= bt_field_class_unsigned_enumeration_create(ir_tc
);
77 ctf_field_class_int_set_props((void *) fc
, ir_fc
);
79 for (i
= 0; i
< fc
->mappings
->len
; i
++) {
80 struct ctf_field_class_enum_mapping
*mapping
=
81 ctf_field_class_enum_borrow_mapping_by_index(fc
, i
);
83 if (fc
->base
.is_signed
) {
84 ret
= bt_field_class_signed_enumeration_map_range(
85 ir_fc
, mapping
->label
->str
,
86 mapping
->range
.lower
.i
, mapping
->range
.upper
.i
);
88 ret
= bt_field_class_unsigned_enumeration_map_range(
89 ir_fc
, mapping
->label
->str
,
90 mapping
->range
.lower
.u
, mapping
->range
.upper
.u
);
100 bt_field_class
*ctf_field_class_float_to_ir(bt_trace_class
*ir_tc
,
101 struct ctf_field_class_float
*fc
)
103 bt_field_class
*ir_fc
;
105 ir_fc
= bt_field_class_real_create(ir_tc
);
108 if (fc
->base
.size
== 32) {
109 bt_field_class_real_set_is_single_precision(ir_fc
,
117 bt_field_class
*ctf_field_class_string_to_ir(bt_trace_class
*ir_tc
,
118 struct ctf_field_class_string
*fc
)
120 bt_field_class
*ir_fc
= bt_field_class_string_create(ir_tc
);
127 bt_field_class
*ctf_field_class_struct_to_ir(bt_trace_class
*ir_tc
,
128 struct ctf_field_class_struct
*fc
,
129 struct ctf_trace_class
*tc
,
130 struct ctf_stream_class
*sc
,
131 struct ctf_event_class
*ec
)
134 bt_field_class
*ir_fc
= bt_field_class_structure_create(ir_tc
);
139 for (i
= 0; i
< fc
->members
->len
; i
++) {
140 struct ctf_named_field_class
*named_fc
=
141 ctf_field_class_struct_borrow_member_by_index(fc
, i
);
142 bt_field_class
*member_ir_fc
;
144 if (!named_fc
->fc
->in_ir
) {
148 member_ir_fc
= ctf_field_class_to_ir(ir_tc
, named_fc
->fc
,
150 BT_ASSERT(member_ir_fc
);
151 ret
= bt_field_class_structure_append_member(
152 ir_fc
, named_fc
->name
->str
, member_ir_fc
);
154 bt_field_class_put_ref(member_ir_fc
);
161 bt_field_class
*borrow_ir_ft_from_field_path(struct ctf_field_path
*field_path
,
162 struct ctf_trace_class
*tc
,
163 struct ctf_stream_class
*sc
,
164 struct ctf_event_class
*ec
)
166 bt_field_class
*ir_fc
= NULL
;
167 struct ctf_field_class
*fc
= ctf_field_path_borrow_field_class(
168 field_path
, tc
, sc
, ec
);
180 bt_field_class
*ctf_field_class_variant_to_ir(bt_trace_class
*ir_tc
,
181 struct ctf_field_class_variant
*fc
,
182 struct ctf_trace_class
*tc
,
183 struct ctf_stream_class
*sc
,
184 struct ctf_event_class
*ec
)
187 bt_field_class
*ir_fc
= bt_field_class_variant_create(ir_tc
);
191 ret
= bt_field_class_variant_set_selector_field_class(
192 ir_fc
, borrow_ir_ft_from_field_path(&fc
->tag_path
, tc
, sc
, ec
));
195 for (i
= 0; i
< fc
->options
->len
; i
++) {
196 struct ctf_named_field_class
*named_fc
=
197 ctf_field_class_variant_borrow_option_by_index(fc
, i
);
198 bt_field_class
*option_ir_fc
;
200 BT_ASSERT(named_fc
->fc
->in_ir
);
201 option_ir_fc
= ctf_field_class_to_ir(ir_tc
, named_fc
->fc
,
203 BT_ASSERT(option_ir_fc
);
204 ret
= bt_field_class_variant_append_option(
205 ir_fc
, named_fc
->name
->str
, option_ir_fc
);
207 bt_field_class_put_ref(option_ir_fc
);
214 bt_field_class
*ctf_field_class_array_to_ir(bt_trace_class
*ir_tc
,
215 struct ctf_field_class_array
*fc
,
216 struct ctf_trace_class
*tc
,
217 struct ctf_stream_class
*sc
,
218 struct ctf_event_class
*ec
)
220 bt_field_class
*ir_fc
;
221 bt_field_class
*elem_ir_fc
;
223 if (fc
->base
.is_text
) {
224 ir_fc
= bt_field_class_string_create(ir_tc
);
229 elem_ir_fc
= ctf_field_class_to_ir(ir_tc
, fc
->base
.elem_fc
, tc
, sc
, ec
);
230 BT_ASSERT(elem_ir_fc
);
231 ir_fc
= bt_field_class_static_array_create(ir_tc
, elem_ir_fc
,
234 bt_field_class_put_ref(elem_ir_fc
);
241 bt_field_class
*ctf_field_class_sequence_to_ir(bt_trace_class
*ir_tc
,
242 struct ctf_field_class_sequence
*fc
,
243 struct ctf_trace_class
*tc
,
244 struct ctf_stream_class
*sc
,
245 struct ctf_event_class
*ec
)
248 bt_field_class
*ir_fc
;
249 bt_field_class
*elem_ir_fc
;
251 if (fc
->base
.is_text
) {
252 ir_fc
= bt_field_class_string_create(ir_tc
);
257 elem_ir_fc
= ctf_field_class_to_ir(ir_tc
, fc
->base
.elem_fc
, tc
, sc
, ec
);
258 BT_ASSERT(elem_ir_fc
);
259 ir_fc
= bt_field_class_dynamic_array_create(ir_tc
, elem_ir_fc
);
261 bt_field_class_put_ref(elem_ir_fc
);
263 ret
= bt_field_class_dynamic_array_set_length_field_class(
265 borrow_ir_ft_from_field_path(&fc
->length_path
, tc
, sc
, ec
));
273 bt_field_class
*ctf_field_class_to_ir(bt_trace_class
*ir_tc
,
274 struct ctf_field_class
*fc
,
275 struct ctf_trace_class
*tc
,
276 struct ctf_stream_class
*sc
,
277 struct ctf_event_class
*ec
)
279 bt_field_class
*ir_fc
= NULL
;
282 BT_ASSERT(fc
->in_ir
);
285 case CTF_FIELD_CLASS_TYPE_INT
:
286 ir_fc
= ctf_field_class_int_to_ir(ir_tc
, (void *) fc
);
288 case CTF_FIELD_CLASS_TYPE_ENUM
:
289 ir_fc
= ctf_field_class_enum_to_ir(ir_tc
, (void *) fc
);
291 case CTF_FIELD_CLASS_TYPE_FLOAT
:
292 ir_fc
= ctf_field_class_float_to_ir(ir_tc
, (void *) fc
);
294 case CTF_FIELD_CLASS_TYPE_STRING
:
295 ir_fc
= ctf_field_class_string_to_ir(ir_tc
, (void *) fc
);
297 case CTF_FIELD_CLASS_TYPE_STRUCT
:
298 ir_fc
= ctf_field_class_struct_to_ir(ir_tc
, (void *) fc
,
301 case CTF_FIELD_CLASS_TYPE_ARRAY
:
302 ir_fc
= ctf_field_class_array_to_ir(ir_tc
, (void *) fc
,
305 case CTF_FIELD_CLASS_TYPE_SEQUENCE
:
306 ir_fc
= ctf_field_class_sequence_to_ir(ir_tc
, (void *) fc
,
309 case CTF_FIELD_CLASS_TYPE_VARIANT
:
310 ir_fc
= ctf_field_class_variant_to_ir(ir_tc
, (void *) fc
,
322 bool ctf_field_class_struct_has_immediate_member_in_ir(
323 struct ctf_field_class_struct
*fc
)
326 bool has_immediate_member_in_ir
= false;
328 for (i
= 0; i
< fc
->members
->len
; i
++) {
329 struct ctf_named_field_class
*named_fc
=
330 ctf_field_class_struct_borrow_member_by_index(fc
, i
);
332 if (named_fc
->fc
->in_ir
) {
333 has_immediate_member_in_ir
= true;
339 return has_immediate_member_in_ir
;
343 bt_field_class
*scope_ctf_field_class_to_ir(bt_trace_class
*ir_tc
,
344 struct ctf_field_class
*fc
,
345 struct ctf_trace_class
*tc
,
346 struct ctf_stream_class
*sc
,
347 struct ctf_event_class
*ec
)
349 bt_field_class
*ir_fc
= NULL
;
355 BT_ASSERT(fc
->type
== CTF_FIELD_CLASS_TYPE_STRUCT
);
357 if (!ctf_field_class_struct_has_immediate_member_in_ir((void *) fc
)) {
359 * Nothing for IR in this scope: typical for packet
360 * header, packet context, and event header.
365 ir_fc
= ctf_field_class_to_ir(ir_tc
, fc
, tc
, sc
, ec
);
372 struct ctf_field_class_int
*borrow_named_int_field_class(
373 struct ctf_field_class_struct
*struct_fc
, const char *name
)
375 struct ctf_named_field_class
*named_fc
= NULL
;
376 struct ctf_field_class_int
*int_fc
= NULL
;
382 named_fc
= ctf_field_class_struct_borrow_member_by_name(struct_fc
, name
);
387 if (named_fc
->fc
->type
!= CTF_FIELD_CLASS_TYPE_INT
&&
388 named_fc
->fc
->type
!= CTF_FIELD_CLASS_TYPE_ENUM
) {
392 int_fc
= (void *) named_fc
->fc
;
399 bt_event_class
*ctf_event_class_to_ir(struct ctf_event_class
*ec
,
400 bt_stream_class
*ir_sc
, struct ctf_trace_class
*tc
,
401 struct ctf_stream_class
*sc
)
404 bt_event_class
*ir_ec
= NULL
;
405 bt_trace_class
*ir_tc
= bt_stream_class_borrow_trace_class(ir_sc
);
407 if (ec
->is_translated
) {
408 ir_ec
= bt_stream_class_borrow_event_class_by_id(
414 ir_ec
= bt_event_class_create_with_id(ir_sc
, ec
->id
);
416 bt_event_class_put_ref(ir_ec
);
418 if (ec
->spec_context_fc
) {
419 bt_field_class
*ir_fc
= scope_ctf_field_class_to_ir(ir_tc
,
420 ec
->spec_context_fc
, tc
, sc
, ec
);
423 ret
= bt_event_class_set_specific_context_field_class(
426 bt_field_class_put_ref(ir_fc
);
430 if (ec
->payload_fc
) {
431 bt_field_class
*ir_fc
= scope_ctf_field_class_to_ir(ir_tc
,
432 ec
->payload_fc
, tc
, sc
, ec
);
435 ret
= bt_event_class_set_payload_field_class(ir_ec
,
438 bt_field_class_put_ref(ir_fc
);
442 if (ec
->name
->len
> 0) {
443 ret
= bt_event_class_set_name(ir_ec
, ec
->name
->str
);
447 if (ec
->emf_uri
->len
> 0) {
448 ret
= bt_event_class_set_emf_uri(ir_ec
, ec
->emf_uri
->str
);
452 if (ec
->log_level
!= -1) {
453 bt_event_class_set_log_level(ir_ec
, ec
->log_level
);
456 ec
->is_translated
= true;
465 bt_stream_class
*ctf_stream_class_to_ir(struct ctf_stream_class
*sc
,
466 bt_trace_class
*ir_tc
, struct ctf_trace_class
*tc
)
469 bt_stream_class
*ir_sc
= NULL
;
470 struct ctf_field_class_int
*int_fc
;
472 if (sc
->is_translated
) {
473 ir_sc
= bt_trace_class_borrow_stream_class_by_id(ir_tc
, sc
->id
);
478 ir_sc
= bt_stream_class_create_with_id(ir_tc
, sc
->id
);
480 bt_stream_class_put_ref(ir_sc
);
482 if (sc
->packet_context_fc
) {
483 bt_field_class
*ir_fc
= scope_ctf_field_class_to_ir(ir_tc
,
484 sc
->packet_context_fc
, tc
, sc
, NULL
);
487 ret
= bt_stream_class_set_packet_context_field_class(
490 bt_field_class_put_ref(ir_fc
);
494 if (sc
->event_header_fc
) {
495 bt_field_class
*ir_fc
= scope_ctf_field_class_to_ir(ir_tc
,
496 sc
->event_header_fc
, tc
, sc
, NULL
);
499 ret
= bt_stream_class_set_event_header_field_class(
502 bt_field_class_put_ref(ir_fc
);
506 if (sc
->event_common_context_fc
) {
507 bt_field_class
*ir_fc
= scope_ctf_field_class_to_ir(ir_tc
,
508 sc
->event_common_context_fc
, tc
, sc
, NULL
);
511 ret
= bt_stream_class_set_event_common_context_field_class(
514 bt_field_class_put_ref(ir_fc
);
518 bt_stream_class_set_assigns_automatic_event_class_id(ir_sc
,
520 bt_stream_class_set_assigns_automatic_stream_id(ir_sc
, BT_FALSE
);
522 if (sc
->default_clock_class
) {
523 BT_ASSERT(sc
->default_clock_class
->ir_cc
);
524 ret
= bt_stream_class_set_default_clock_class(ir_sc
,
525 sc
->default_clock_class
->ir_cc
);
529 int_fc
= borrow_named_int_field_class((void *) sc
->packet_context_fc
,
532 if (int_fc
->meaning
== CTF_FIELD_CLASS_MEANING_DISC_EV_REC_COUNTER_SNAPSHOT
) {
533 bt_stream_class_set_packets_have_discarded_event_counter_snapshot(
538 int_fc
= borrow_named_int_field_class((void *) sc
->packet_context_fc
,
541 if (int_fc
->meaning
== CTF_FIELD_CLASS_MEANING_PACKET_COUNTER_SNAPSHOT
) {
542 bt_stream_class_set_packets_have_packet_counter_snapshot(
547 int_fc
= borrow_named_int_field_class((void *) sc
->packet_context_fc
,
550 if (int_fc
->meaning
== CTF_FIELD_CLASS_MEANING_PACKET_BEGINNING_TIME
) {
551 bt_stream_class_set_packets_have_default_beginning_clock_snapshot(
556 int_fc
= borrow_named_int_field_class((void *) sc
->packet_context_fc
,
559 if (int_fc
->meaning
== CTF_FIELD_CLASS_MEANING_PACKET_END_TIME
) {
560 bt_stream_class_set_packets_have_default_end_clock_snapshot(
565 sc
->is_translated
= true;
573 void ctf_clock_class_to_ir(bt_clock_class
*ir_cc
, struct ctf_clock_class
*cc
)
577 if (strlen(cc
->name
->str
) > 0) {
578 ret
= bt_clock_class_set_name(ir_cc
, cc
->name
->str
);
582 if (strlen(cc
->description
->str
) > 0) {
583 ret
= bt_clock_class_set_description(ir_cc
, cc
->description
->str
);
587 bt_clock_class_set_frequency(ir_cc
, cc
->frequency
);
588 bt_clock_class_set_precision(ir_cc
, cc
->precision
);
589 bt_clock_class_set_offset(ir_cc
, cc
->offset_seconds
, cc
->offset_cycles
);
592 bt_clock_class_set_uuid(ir_cc
, cc
->uuid
);
595 bt_clock_class_set_is_absolute(ir_cc
, cc
->is_absolute
);
599 int ctf_trace_class_to_ir(bt_trace_class
*ir_tc
, struct ctf_trace_class
*tc
)
604 if (tc
->is_translated
) {
608 if (tc
->packet_header_fc
) {
609 bt_field_class
*ir_fc
= scope_ctf_field_class_to_ir(ir_tc
,
610 tc
->packet_header_fc
, tc
, NULL
, NULL
);
613 ret
= bt_trace_class_set_packet_header_field_class(
616 bt_field_class_put_ref(ir_fc
);
620 if (tc
->is_uuid_set
) {
621 bt_trace_class_set_uuid(ir_tc
, tc
->uuid
);
624 for (i
= 0; i
< tc
->env_entries
->len
; i
++) {
625 struct ctf_trace_class_env_entry
*env_entry
=
626 ctf_trace_class_borrow_env_entry_by_index(tc
, i
);
628 switch (env_entry
->type
) {
629 case CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT
:
630 ret
= bt_trace_class_set_environment_entry_integer(
631 ir_tc
, env_entry
->name
->str
,
634 case CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR
:
635 ret
= bt_trace_class_set_environment_entry_string(
636 ir_tc
, env_entry
->name
->str
,
637 env_entry
->value
.str
->str
);
648 for (i
= 0; i
< tc
->clock_classes
->len
; i
++) {
649 struct ctf_clock_class
*cc
= tc
->clock_classes
->pdata
[i
];
651 cc
->ir_cc
= bt_clock_class_create(ir_tc
);
652 ctf_clock_class_to_ir(cc
->ir_cc
, cc
);
655 bt_trace_class_set_assigns_automatic_stream_class_id(ir_tc
,
657 tc
->is_translated
= true;
665 int ctf_trace_class_translate(bt_trace_class
*ir_tc
,
666 struct ctf_trace_class
*tc
)
671 ret
= ctf_trace_class_to_ir(ir_tc
, tc
);
676 for (i
= 0; i
< tc
->stream_classes
->len
; i
++) {
678 struct ctf_stream_class
*sc
= tc
->stream_classes
->pdata
[i
];
679 bt_stream_class
*ir_sc
;
681 ir_sc
= ctf_stream_class_to_ir(sc
, ir_tc
, tc
);
687 for (j
= 0; j
< sc
->event_classes
->len
; j
++) {
688 struct ctf_event_class
*ec
= sc
->event_classes
->pdata
[j
];
689 bt_event_class
*ir_ec
;
691 ir_ec
= ctf_event_class_to_ir(ec
, ir_sc
, tc
, sc
);