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 struct bt_private_field_class
*ctf_field_class_to_ir(struct ctf_field_class
*fc
,
30 struct ctf_trace_class
*tc
,
31 struct ctf_stream_class
*sc
,
32 struct ctf_event_class
*ec
);
35 void ctf_field_class_int_set_props(struct ctf_field_class_int
*fc
,
36 struct bt_private_field_class
*ir_fc
)
40 ret
= bt_private_field_class_integer_set_field_value_range(ir_fc
,
43 ret
= bt_private_field_class_integer_set_preferred_display_base(ir_fc
,
49 struct bt_private_field_class
*ctf_field_class_int_to_ir(
50 struct ctf_field_class_int
*fc
)
52 struct bt_private_field_class
*ir_fc
;
55 ir_fc
= bt_private_field_class_signed_integer_create();
57 ir_fc
= bt_private_field_class_unsigned_integer_create();
61 ctf_field_class_int_set_props(fc
, ir_fc
);
66 struct bt_private_field_class
*ctf_field_class_enum_to_ir(
67 struct ctf_field_class_enum
*fc
)
70 struct bt_private_field_class
*ir_fc
;
73 if (fc
->base
.is_signed
) {
74 ir_fc
= bt_private_field_class_signed_enumeration_create();
76 ir_fc
= bt_private_field_class_unsigned_enumeration_create();
80 ctf_field_class_int_set_props((void *) fc
, ir_fc
);
82 for (i
= 0; i
< fc
->mappings
->len
; i
++) {
83 struct ctf_field_class_enum_mapping
*mapping
=
84 ctf_field_class_enum_borrow_mapping_by_index(fc
, i
);
86 if (fc
->base
.is_signed
) {
87 ret
= bt_private_field_class_signed_enumeration_map_range(
88 ir_fc
, mapping
->label
->str
,
89 mapping
->range
.lower
.i
, mapping
->range
.upper
.i
);
91 ret
= bt_private_field_class_unsigned_enumeration_map_range(
92 ir_fc
, mapping
->label
->str
,
93 mapping
->range
.lower
.u
, mapping
->range
.upper
.u
);
103 struct bt_private_field_class
*ctf_field_class_float_to_ir(
104 struct ctf_field_class_float
*fc
)
106 struct bt_private_field_class
*ir_fc
;
109 ir_fc
= bt_private_field_class_real_create();
112 if (fc
->base
.size
== 32) {
113 ret
= bt_private_field_class_real_set_is_single_precision(ir_fc
,
122 struct bt_private_field_class
*ctf_field_class_string_to_ir(
123 struct ctf_field_class_string
*fc
)
125 struct bt_private_field_class
*ir_fc
=
126 bt_private_field_class_string_create();
133 struct bt_private_field_class
*ctf_field_class_struct_to_ir(
134 struct ctf_field_class_struct
*fc
,
135 struct ctf_trace_class
*tc
,
136 struct ctf_stream_class
*sc
,
137 struct ctf_event_class
*ec
)
140 struct bt_private_field_class
*ir_fc
=
141 bt_private_field_class_structure_create();
146 for (i
= 0; i
< fc
->members
->len
; i
++) {
147 struct ctf_named_field_class
*named_fc
=
148 ctf_field_class_struct_borrow_member_by_index(fc
, i
);
149 struct bt_private_field_class
*member_ir_fc
;
151 if (!named_fc
->fc
->in_ir
) {
155 member_ir_fc
= ctf_field_class_to_ir(named_fc
->fc
, tc
, sc
, ec
);
156 BT_ASSERT(member_ir_fc
);
157 ret
= bt_private_field_class_structure_append_member(
158 ir_fc
, named_fc
->name
->str
, member_ir_fc
);
160 bt_object_put_ref(member_ir_fc
);
167 struct bt_private_field_class
*borrow_ir_ft_from_field_path(
168 struct ctf_field_path
*field_path
,
169 struct ctf_trace_class
*tc
,
170 struct ctf_stream_class
*sc
,
171 struct ctf_event_class
*ec
)
173 struct bt_private_field_class
*ir_fc
= NULL
;
174 struct ctf_field_class
*fc
= ctf_field_path_borrow_field_class(
175 field_path
, tc
, sc
, ec
);
187 struct bt_private_field_class
*ctf_field_class_variant_to_ir(
188 struct ctf_field_class_variant
*fc
,
189 struct ctf_trace_class
*tc
,
190 struct ctf_stream_class
*sc
,
191 struct ctf_event_class
*ec
)
194 struct bt_private_field_class
*ir_fc
=
195 bt_private_field_class_variant_create();
199 ret
= bt_private_field_class_variant_set_selector_field_class(
200 ir_fc
, borrow_ir_ft_from_field_path(&fc
->tag_path
, tc
, sc
, ec
));
203 for (i
= 0; i
< fc
->options
->len
; i
++) {
204 struct ctf_named_field_class
*named_fc
=
205 ctf_field_class_variant_borrow_option_by_index(fc
, i
);
206 struct bt_private_field_class
*option_ir_fc
;
208 BT_ASSERT(named_fc
->fc
->in_ir
);
209 option_ir_fc
= ctf_field_class_to_ir(named_fc
->fc
, tc
, sc
, ec
);
210 BT_ASSERT(option_ir_fc
);
211 ret
= bt_private_field_class_variant_append_private_option(
212 ir_fc
, named_fc
->name
->str
, option_ir_fc
);
214 bt_object_put_ref(option_ir_fc
);
221 struct bt_private_field_class
*ctf_field_class_array_to_ir(
222 struct ctf_field_class_array
*fc
,
223 struct ctf_trace_class
*tc
,
224 struct ctf_stream_class
*sc
,
225 struct ctf_event_class
*ec
)
227 struct bt_private_field_class
*ir_fc
;
228 struct bt_private_field_class
*elem_ir_fc
;
230 if (fc
->base
.is_text
) {
231 ir_fc
= bt_private_field_class_string_create();
236 elem_ir_fc
= ctf_field_class_to_ir(fc
->base
.elem_fc
, tc
, sc
, ec
);
237 BT_ASSERT(elem_ir_fc
);
238 ir_fc
= bt_private_field_class_static_array_create(elem_ir_fc
,
241 bt_object_put_ref(elem_ir_fc
);
248 struct bt_private_field_class
*ctf_field_class_sequence_to_ir(
249 struct ctf_field_class_sequence
*fc
,
250 struct ctf_trace_class
*tc
,
251 struct ctf_stream_class
*sc
,
252 struct ctf_event_class
*ec
)
255 struct bt_private_field_class
*ir_fc
;
256 struct bt_private_field_class
*elem_ir_fc
;
258 if (fc
->base
.is_text
) {
259 ir_fc
= bt_private_field_class_string_create();
264 elem_ir_fc
= ctf_field_class_to_ir(fc
->base
.elem_fc
, tc
, sc
, ec
);
265 BT_ASSERT(elem_ir_fc
);
266 ir_fc
= bt_private_field_class_dynamic_array_create(elem_ir_fc
);
268 bt_object_put_ref(elem_ir_fc
);
270 ret
= bt_private_field_class_dynamic_array_set_length_field_class(
272 borrow_ir_ft_from_field_path(&fc
->length_path
, tc
, sc
, ec
));
280 struct bt_private_field_class
*ctf_field_class_to_ir(struct ctf_field_class
*fc
,
281 struct ctf_trace_class
*tc
,
282 struct ctf_stream_class
*sc
,
283 struct ctf_event_class
*ec
)
285 struct bt_private_field_class
*ir_fc
= NULL
;
288 BT_ASSERT(fc
->in_ir
);
291 case CTF_FIELD_CLASS_TYPE_INT
:
292 ir_fc
= ctf_field_class_int_to_ir((void *) fc
);
294 case CTF_FIELD_CLASS_TYPE_ENUM
:
295 ir_fc
= ctf_field_class_enum_to_ir((void *) fc
);
297 case CTF_FIELD_CLASS_TYPE_FLOAT
:
298 ir_fc
= ctf_field_class_float_to_ir((void *) fc
);
300 case CTF_FIELD_CLASS_TYPE_STRING
:
301 ir_fc
= ctf_field_class_string_to_ir((void *) fc
);
303 case CTF_FIELD_CLASS_TYPE_STRUCT
:
304 ir_fc
= ctf_field_class_struct_to_ir((void *) fc
, tc
, sc
, ec
);
306 case CTF_FIELD_CLASS_TYPE_ARRAY
:
307 ir_fc
= ctf_field_class_array_to_ir((void *) fc
, tc
, sc
, ec
);
309 case CTF_FIELD_CLASS_TYPE_SEQUENCE
:
310 ir_fc
= ctf_field_class_sequence_to_ir((void *) fc
, tc
, sc
, ec
);
312 case CTF_FIELD_CLASS_TYPE_VARIANT
:
313 ir_fc
= ctf_field_class_variant_to_ir((void *) fc
, tc
, sc
, ec
);
324 bool ctf_field_class_struct_has_immediate_member_in_ir(
325 struct ctf_field_class_struct
*fc
)
328 bool has_immediate_member_in_ir
= false;
330 for (i
= 0; i
< fc
->members
->len
; i
++) {
331 struct ctf_named_field_class
*named_fc
=
332 ctf_field_class_struct_borrow_member_by_index(fc
, i
);
334 if (named_fc
->fc
->in_ir
) {
335 has_immediate_member_in_ir
= true;
341 return has_immediate_member_in_ir
;
345 struct bt_private_field_class
*scope_ctf_field_class_to_ir(struct ctf_field_class
*fc
,
346 struct ctf_trace_class
*tc
,
347 struct ctf_stream_class
*sc
,
348 struct ctf_event_class
*ec
)
350 struct bt_private_field_class
*ir_fc
= NULL
;
356 BT_ASSERT(fc
->type
== CTF_FIELD_CLASS_TYPE_STRUCT
);
358 if (!ctf_field_class_struct_has_immediate_member_in_ir((void *) fc
)) {
360 * Nothing for IR in this scope: typical for packet
361 * header, packet context, and event header.
366 ir_fc
= ctf_field_class_to_ir(fc
, tc
, sc
, ec
);
373 struct ctf_field_class_int
*borrow_named_int_field_class(
374 struct ctf_field_class_struct
*struct_fc
, const char *name
)
376 struct ctf_named_field_class
*named_fc
= NULL
;
377 struct ctf_field_class_int
*int_fc
= NULL
;
383 named_fc
= ctf_field_class_struct_borrow_member_by_name(struct_fc
, name
);
388 if (named_fc
->fc
->type
!= CTF_FIELD_CLASS_TYPE_INT
&&
389 named_fc
->fc
->type
!= CTF_FIELD_CLASS_TYPE_ENUM
) {
393 int_fc
= (void *) named_fc
->fc
;
400 struct bt_private_event_class
*ctf_event_class_to_ir(struct ctf_event_class
*ec
,
401 struct bt_private_stream_class
*ir_sc
, struct ctf_trace_class
*tc
,
402 struct ctf_stream_class
*sc
)
405 struct bt_private_event_class
*ir_ec
= NULL
;
407 if (ec
->is_translated
) {
408 ir_ec
= bt_private_stream_class_borrow_event_class_by_id(
414 ir_ec
= bt_private_event_class_create_with_id(ir_sc
, ec
->id
);
416 bt_object_put_ref(ir_ec
);
418 if (ec
->spec_context_fc
) {
419 struct bt_private_field_class
*ir_fc
= scope_ctf_field_class_to_ir(
420 ec
->spec_context_fc
, tc
, sc
, ec
);
423 ret
= bt_private_event_class_set_specific_context_field_class(
426 bt_object_put_ref(ir_fc
);
430 if (ec
->payload_fc
) {
431 struct bt_private_field_class
*ir_fc
= scope_ctf_field_class_to_ir(
432 ec
->payload_fc
, tc
, sc
, ec
);
435 ret
= bt_private_event_class_set_payload_field_class(ir_ec
,
438 bt_object_put_ref(ir_fc
);
442 if (ec
->name
->len
> 0) {
443 ret
= bt_private_event_class_set_name(ir_ec
, ec
->name
->str
);
447 if (ec
->emf_uri
->len
> 0) {
448 ret
= bt_private_event_class_set_emf_uri(ir_ec
, ec
->emf_uri
->str
);
452 if (ec
->log_level
!= -1) {
453 ret
= bt_private_event_class_set_log_level(ir_ec
, ec
->log_level
);
457 ec
->is_translated
= true;
466 struct bt_private_stream_class
*ctf_stream_class_to_ir(struct ctf_stream_class
*sc
,
467 struct bt_private_trace
*ir_trace
, struct ctf_trace_class
*tc
)
470 struct bt_private_stream_class
*ir_sc
= NULL
;
471 struct ctf_field_class_int
*int_fc
;
473 if (sc
->is_translated
) {
474 ir_sc
= bt_private_trace_borrow_stream_class_by_id(
480 ir_sc
= bt_private_stream_class_create_with_id(ir_trace
, sc
->id
);
482 bt_object_put_ref(ir_sc
);
484 if (sc
->packet_context_fc
) {
485 struct bt_private_field_class
*ir_fc
= scope_ctf_field_class_to_ir(
486 sc
->packet_context_fc
, tc
, sc
, NULL
);
489 ret
= bt_private_stream_class_set_packet_context_field_class(
492 bt_object_put_ref(ir_fc
);
496 if (sc
->event_header_fc
) {
497 struct bt_private_field_class
*ir_fc
= scope_ctf_field_class_to_ir(
498 sc
->event_header_fc
, tc
, sc
, NULL
);
501 ret
= bt_private_stream_class_set_event_header_field_class(
504 bt_object_put_ref(ir_fc
);
508 if (sc
->event_common_context_fc
) {
509 struct bt_private_field_class
*ir_fc
= scope_ctf_field_class_to_ir(
510 sc
->event_common_context_fc
, tc
, sc
, NULL
);
513 ret
= bt_private_stream_class_set_event_common_context_field_class(
516 bt_object_put_ref(ir_fc
);
520 ret
= bt_private_stream_class_set_assigns_automatic_event_class_id(ir_sc
,
523 ret
= bt_private_stream_class_set_assigns_automatic_stream_id(ir_sc
, BT_FALSE
);
526 if (sc
->default_clock_class
) {
527 ret
= bt_private_stream_class_set_default_clock_class(ir_sc
,
528 bt_private_clock_class_borrow_clock_class(sc
->default_clock_class
));
532 int_fc
= borrow_named_int_field_class((void *) sc
->packet_context_fc
,
535 if (int_fc
->meaning
== CTF_FIELD_CLASS_MEANING_DISC_EV_REC_COUNTER_SNAPSHOT
) {
536 ret
= bt_private_stream_class_set_packets_have_discarded_event_counter_snapshot(
542 int_fc
= borrow_named_int_field_class((void *) sc
->packet_context_fc
,
545 if (int_fc
->meaning
== CTF_FIELD_CLASS_MEANING_PACKET_COUNTER_SNAPSHOT
) {
546 ret
= bt_private_stream_class_set_packets_have_packet_counter_snapshot(
552 int_fc
= borrow_named_int_field_class((void *) sc
->packet_context_fc
,
555 if (int_fc
->meaning
== CTF_FIELD_CLASS_MEANING_PACKET_BEGINNING_TIME
) {
556 ret
= bt_private_stream_class_set_packets_have_default_beginning_clock_value(
562 int_fc
= borrow_named_int_field_class((void *) sc
->packet_context_fc
,
565 if (int_fc
->meaning
== CTF_FIELD_CLASS_MEANING_PACKET_END_TIME
) {
566 ret
= bt_private_stream_class_set_packets_have_default_end_clock_value(
572 sc
->is_translated
= true;
580 int ctf_trace_class_to_ir(struct bt_private_trace
*ir_trace
,
581 struct ctf_trace_class
*tc
)
586 if (tc
->is_translated
) {
590 if (tc
->packet_header_fc
) {
591 struct bt_private_field_class
*ir_fc
= scope_ctf_field_class_to_ir(
592 tc
->packet_header_fc
, tc
, NULL
, NULL
);
595 ret
= bt_private_trace_set_packet_header_field_class(
598 bt_object_put_ref(ir_fc
);
602 if (tc
->name
->len
> 0) {
603 ret
= bt_private_trace_set_name(ir_trace
, tc
->name
->str
);
609 if (tc
->is_uuid_set
) {
610 ret
= bt_private_trace_set_uuid(ir_trace
, tc
->uuid
);
616 for (i
= 0; i
< tc
->env_entries
->len
; i
++) {
617 struct ctf_trace_class_env_entry
*env_entry
=
618 ctf_trace_class_borrow_env_entry_by_index(tc
, i
);
620 switch (env_entry
->type
) {
621 case CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT
:
622 ret
= bt_private_trace_set_environment_entry_integer(
623 ir_trace
, env_entry
->name
->str
,
626 case CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR
:
627 ret
= bt_private_trace_set_environment_entry_string(
628 ir_trace
, env_entry
->name
->str
,
629 env_entry
->value
.str
->str
);
640 ret
= bt_private_trace_set_assigns_automatic_stream_class_id(ir_trace
,
646 tc
->is_translated
= true;
647 tc
->ir_tc
= ir_trace
;
654 int ctf_trace_class_translate(struct bt_private_trace
*ir_trace
,
655 struct ctf_trace_class
*tc
)
660 ret
= ctf_trace_class_to_ir(ir_trace
, tc
);
665 for (i
= 0; i
< tc
->stream_classes
->len
; i
++) {
667 struct ctf_stream_class
*sc
= tc
->stream_classes
->pdata
[i
];
668 struct bt_private_stream_class
*ir_sc
;
670 ir_sc
= ctf_stream_class_to_ir(sc
, ir_trace
, tc
);
676 for (j
= 0; j
< sc
->event_classes
->len
; j
++) {
677 struct ctf_event_class
*ec
= sc
->event_classes
->pdata
[j
];
678 struct bt_private_event_class
*ir_ec
;
680 ir_ec
= ctf_event_class_to_ir(ec
, ir_sc
, tc
, sc
);