2 * Copyright 2019 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.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 #include <babeltrace2/babeltrace.h>
24 #include "common/macros.h"
29 #include "common/assert.h"
30 #include "compat/endian.h"
32 #include "fs-sink-ctf-meta.h"
35 unsigned int indent_level
;
40 void append_indent(struct ctx
*ctx
)
44 for (i
= 0; i
< ctx
->indent_level
; i
++) {
45 g_string_append_c(ctx
->tsdl
, '\t');
50 void append_uuid(struct ctx
*ctx
, bt_uuid uuid
)
52 g_string_append_printf(ctx
->tsdl
,
53 "\"" BT_UUID_FMT
"\"",
54 BT_UUID_FMT_VALUES(uuid
));
58 void append_quoted_string_content(struct ctx
*ctx
, const char *str
)
62 for (ch
= str
; *ch
!= '\0'; ch
++) {
63 unsigned char uch
= (unsigned char) *ch
;
65 if (uch
< 32 || uch
>= 127) {
68 g_string_append(ctx
->tsdl
, "\\a");
71 g_string_append(ctx
->tsdl
, "\\b");
74 g_string_append(ctx
->tsdl
, "\\f");
77 g_string_append(ctx
->tsdl
, "\\n");
80 g_string_append(ctx
->tsdl
, "\\r");
83 g_string_append(ctx
->tsdl
, "\\t");
86 g_string_append(ctx
->tsdl
, "\\v");
89 g_string_append_printf(ctx
->tsdl
, "\\x%02x",
93 } else if (*ch
== '"' || *ch
== '\\') {
94 g_string_append_c(ctx
->tsdl
, '\\');
95 g_string_append_c(ctx
->tsdl
, *ch
);
97 g_string_append_c(ctx
->tsdl
, *ch
);
103 void append_quoted_string(struct ctx
*ctx
, const char *str
)
105 g_string_append_c(ctx
->tsdl
, '"');
106 append_quoted_string_content(ctx
, str
);
107 g_string_append_c(ctx
->tsdl
, '"');
111 void append_integer_field_class_from_props(struct ctx
*ctx
, unsigned int size
,
112 unsigned int alignment
, bool is_signed
,
113 bt_field_class_integer_preferred_display_base disp_base
,
114 const char *mapped_clock_class_name
, const char *field_name
,
117 g_string_append_printf(ctx
->tsdl
,
118 "integer { size = %u; align = %u;",
122 g_string_append(ctx
->tsdl
, " signed = true;");
125 if (disp_base
!= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
) {
126 g_string_append(ctx
->tsdl
, " base = ");
129 case BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY
:
130 g_string_append(ctx
->tsdl
, "b");
132 case BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL
:
133 g_string_append(ctx
->tsdl
, "o");
135 case BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
:
136 g_string_append(ctx
->tsdl
, "x");
142 g_string_append_c(ctx
->tsdl
, ';');
145 if (mapped_clock_class_name
) {
146 g_string_append_printf(ctx
->tsdl
, " map = clock.%s.value;",
147 mapped_clock_class_name
);
150 g_string_append(ctx
->tsdl
, " }");
153 g_string_append_printf(ctx
->tsdl
, " %s", field_name
);
157 g_string_append(ctx
->tsdl
, ";\n");
162 void append_end_block(struct ctx
*ctx
)
166 g_string_append(ctx
->tsdl
, "}");
170 void append_end_block_semi_nl(struct ctx
*ctx
)
174 g_string_append(ctx
->tsdl
, "};\n");
178 void append_end_block_semi_nl_nl(struct ctx
*ctx
)
180 append_end_block_semi_nl(ctx
);
181 g_string_append_c(ctx
->tsdl
, '\n');
185 void append_bool_field_class(struct ctx
*ctx
,
186 __attribute__((unused
)) struct fs_sink_ctf_field_class_bool
*fc
)
189 * CTF 1.8 has no boolean field class type, so this component
190 * translates it to an 8-bit unsigned integer field class.
192 append_integer_field_class_from_props(ctx
, fc
->base
.size
,
193 fc
->base
.base
.alignment
, false,
194 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
,
199 void append_integer_field_class(struct ctx
*ctx
,
200 struct fs_sink_ctf_field_class_int
*fc
)
202 const bt_field_class
*ir_fc
= fc
->base
.base
.ir_fc
;
203 bt_field_class_type type
= bt_field_class_get_type(ir_fc
);
204 bool is_signed
= type
== BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
||
205 type
== BT_FIELD_CLASS_TYPE_SIGNED_INTEGER
;
207 if (type
== BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
||
208 type
== BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
) {
209 g_string_append(ctx
->tsdl
, "enum : ");
212 append_integer_field_class_from_props(ctx
, fc
->base
.size
,
213 fc
->base
.base
.alignment
, is_signed
,
214 bt_field_class_integer_get_preferred_display_base(ir_fc
),
217 if (type
== BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
||
218 type
== BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
) {
221 g_string_append(ctx
->tsdl
, " {\n");
224 for (i
= 0; i
< bt_field_class_enumeration_get_mapping_count(ir_fc
); i
++) {
226 const bt_field_class_enumeration_mapping
*mapping
;
227 const bt_field_class_enumeration_unsigned_mapping
*u_mapping
;
228 const bt_field_class_enumeration_signed_mapping
*s_mapping
;
229 const bt_integer_range_set
*ranges
;
230 const bt_integer_range_set_unsigned
*u_ranges
;
231 const bt_integer_range_set_signed
*s_ranges
;
232 uint64_t range_count
;
236 s_mapping
= bt_field_class_enumeration_signed_borrow_mapping_by_index_const(
238 mapping
= bt_field_class_enumeration_signed_mapping_as_mapping_const(
240 s_ranges
= bt_field_class_enumeration_signed_mapping_borrow_ranges_const(
242 ranges
= bt_integer_range_set_signed_as_range_set_const(
245 u_mapping
= bt_field_class_enumeration_unsigned_borrow_mapping_by_index_const(
247 mapping
= bt_field_class_enumeration_unsigned_mapping_as_mapping_const(
249 u_ranges
= bt_field_class_enumeration_unsigned_mapping_borrow_ranges_const(
251 ranges
= bt_integer_range_set_unsigned_as_range_set_const(
255 label
= bt_field_class_enumeration_mapping_get_label(
257 range_count
= bt_integer_range_set_get_range_count(
260 for (range_i
= 0; range_i
< range_count
; range_i
++) {
262 g_string_append(ctx
->tsdl
, "\"");
263 append_quoted_string_content(ctx
, label
);
264 g_string_append(ctx
->tsdl
, "\" = ");
267 const bt_integer_range_signed
*range
;
268 int64_t lower
, upper
;
270 range
= bt_integer_range_set_signed_borrow_range_by_index_const(
272 lower
= bt_integer_range_signed_get_lower(
274 upper
= bt_integer_range_signed_get_upper(
277 if (lower
== upper
) {
278 g_string_append_printf(
279 ctx
->tsdl
, "%" PRId64
,
282 g_string_append_printf(
283 ctx
->tsdl
, "%" PRId64
" ... %" PRId64
,
287 const bt_integer_range_unsigned
*range
;
288 uint64_t lower
, upper
;
290 range
= bt_integer_range_set_unsigned_borrow_range_by_index_const(
292 lower
= bt_integer_range_unsigned_get_lower(
294 upper
= bt_integer_range_unsigned_get_upper(
297 if (lower
== upper
) {
298 g_string_append_printf(
299 ctx
->tsdl
, "%" PRIu64
,
302 g_string_append_printf(
303 ctx
->tsdl
, "%" PRIu64
" ... %" PRIu64
,
308 g_string_append(ctx
->tsdl
, ",\n");
312 append_end_block(ctx
);
317 void append_float_field_class(struct ctx
*ctx
,
318 struct fs_sink_ctf_field_class_float
*fc
)
320 unsigned int mant_dig
, exp_dig
;
322 if (bt_field_class_real_is_single_precision(fc
->base
.base
.ir_fc
)) {
330 g_string_append_printf(ctx
->tsdl
,
331 "floating_point { mant_dig = %u; exp_dig = %u; align = %u; }",
332 mant_dig
, exp_dig
, fc
->base
.base
.alignment
);
336 void append_string_field_class(struct ctx
*ctx
,
337 struct fs_sink_ctf_field_class_float
*fc
)
339 g_string_append(ctx
->tsdl
, "string { encoding = UTF8; }");
343 void append_field_class(struct ctx
*ctx
, struct fs_sink_ctf_field_class
*fc
);
346 void append_member(struct ctx
*ctx
, const char *name
,
347 struct fs_sink_ctf_field_class
*fc
)
349 GString
*lengths
= NULL
;
350 const char *lengths_str
= "";
352 while (fc
->type
== FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY
||
353 fc
->type
== FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE
) {
355 lengths
= g_string_new(NULL
);
359 if (fc
->type
== FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY
) {
360 struct fs_sink_ctf_field_class_array
*array_fc
=
363 g_string_append_printf(lengths
, "[%" PRIu64
"]",
365 fc
= array_fc
->base
.elem_fc
;
367 struct fs_sink_ctf_field_class_sequence
*seq_fc
=
370 g_string_append_printf(lengths
, "[%s]",
371 seq_fc
->length_ref
->str
);
372 fc
= seq_fc
->base
.elem_fc
;
376 append_field_class(ctx
, fc
);
379 lengths_str
= lengths
->str
;
382 g_string_append_printf(ctx
->tsdl
, " %s%s;\n", name
, lengths_str
);
385 g_string_free(lengths
, TRUE
);
390 void append_struct_field_class_members(struct ctx
*ctx
,
391 struct fs_sink_ctf_field_class_struct
*struct_fc
)
395 for (i
= 0; i
< struct_fc
->members
->len
; i
++) {
396 struct fs_sink_ctf_named_field_class
*named_fc
=
397 fs_sink_ctf_field_class_struct_borrow_member_by_index(
399 struct fs_sink_ctf_field_class
*fc
= named_fc
->fc
;
401 if (fc
->type
== FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE
) {
402 struct fs_sink_ctf_field_class_sequence
*seq_fc
=
405 if (seq_fc
->length_is_before
) {
407 append_integer_field_class_from_props(ctx
,
409 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
,
410 NULL
, seq_fc
->length_ref
->str
, true);
412 } else if (fc
->type
== FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT
) {
413 struct fs_sink_ctf_field_class_variant
*var_fc
=
416 if (var_fc
->tag_is_before
) {
418 g_string_append(ctx
->tsdl
, "enum : ");
419 append_integer_field_class_from_props(ctx
,
421 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
,
423 g_string_append(ctx
->tsdl
, " {\n");
426 for (i
= 0; i
< var_fc
->options
->len
; i
++) {
427 struct fs_sink_ctf_named_field_class
*named_fc
=
428 fs_sink_ctf_field_class_variant_borrow_option_by_index(
432 g_string_append_printf(ctx
->tsdl
,
433 "\"%s\" = %" PRIu64
",\n",
434 named_fc
->name
->str
, i
);
437 append_end_block(ctx
);
438 g_string_append_printf(ctx
->tsdl
, " %s;\n",
439 var_fc
->tag_ref
->str
);
441 } else if (fc
->type
== FS_SINK_CTF_FIELD_CLASS_TYPE_BOOL
) {
443 g_string_append(ctx
->tsdl
,
444 "/* The integer field class below was a trace IR boolean field class. */\n");
448 append_member(ctx
, named_fc
->name
->str
, fc
);
453 void append_struct_field_class(struct ctx
*ctx
,
454 struct fs_sink_ctf_field_class_struct
*fc
)
456 g_string_append(ctx
->tsdl
, "struct {\n");
458 append_struct_field_class_members(ctx
, fc
);
459 append_end_block(ctx
);
460 g_string_append_printf(ctx
->tsdl
, " align(%u)",
465 void append_variant_field_class(struct ctx
*ctx
,
466 struct fs_sink_ctf_field_class_variant
*var_fc
)
470 g_string_append_printf(ctx
->tsdl
, "variant <%s> {\n",
471 var_fc
->tag_ref
->str
);
474 for (i
= 0; i
< var_fc
->options
->len
; i
++) {
475 struct fs_sink_ctf_named_field_class
*named_fc
=
476 fs_sink_ctf_field_class_variant_borrow_option_by_index(
480 append_member(ctx
, named_fc
->name
->str
, named_fc
->fc
);
483 append_end_block(ctx
);
487 void append_field_class(struct ctx
*ctx
, struct fs_sink_ctf_field_class
*fc
)
490 case FS_SINK_CTF_FIELD_CLASS_TYPE_BOOL
:
491 append_bool_field_class(ctx
, (void *) fc
);
493 case FS_SINK_CTF_FIELD_CLASS_TYPE_INT
:
494 append_integer_field_class(ctx
, (void *) fc
);
496 case FS_SINK_CTF_FIELD_CLASS_TYPE_FLOAT
:
497 append_float_field_class(ctx
, (void *) fc
);
499 case FS_SINK_CTF_FIELD_CLASS_TYPE_STRING
:
500 append_string_field_class(ctx
, (void *) fc
);
502 case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT
:
503 append_struct_field_class(ctx
, (void *) fc
);
505 case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT
:
506 append_variant_field_class(ctx
, (void *) fc
);
514 void append_event_class(struct ctx
*ctx
, struct fs_sink_ctf_event_class
*ec
)
517 bt_event_class_log_level log_level
;
521 g_string_append(ctx
->tsdl
, "event {\n");
524 /* Event class properties */
526 g_string_append(ctx
->tsdl
, "name = ");
527 str
= bt_event_class_get_name(ec
->ir_ec
);
532 append_quoted_string(ctx
, str
);
533 g_string_append(ctx
->tsdl
, ";\n");
535 g_string_append_printf(ctx
->tsdl
, "stream_id = %" PRIu64
";\n",
536 bt_stream_class_get_id(ec
->sc
->ir_sc
));
538 g_string_append_printf(ctx
->tsdl
, "id = %" PRIu64
";\n",
539 bt_event_class_get_id(ec
->ir_ec
));
541 str
= bt_event_class_get_emf_uri(ec
->ir_ec
);
544 g_string_append(ctx
->tsdl
, "model.emf.uri = ");
545 append_quoted_string(ctx
, str
);
546 g_string_append(ctx
->tsdl
, ";\n");
549 if (bt_event_class_get_log_level(ec
->ir_ec
, &log_level
) ==
550 BT_PROPERTY_AVAILABILITY_AVAILABLE
) {
554 g_string_append(ctx
->tsdl
, "loglevel = ");
557 case BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY
:
560 case BT_EVENT_CLASS_LOG_LEVEL_ALERT
:
563 case BT_EVENT_CLASS_LOG_LEVEL_CRITICAL
:
566 case BT_EVENT_CLASS_LOG_LEVEL_ERROR
:
569 case BT_EVENT_CLASS_LOG_LEVEL_WARNING
:
572 case BT_EVENT_CLASS_LOG_LEVEL_NOTICE
:
575 case BT_EVENT_CLASS_LOG_LEVEL_INFO
:
578 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM
:
581 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM
:
584 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS
:
587 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE
:
590 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT
:
593 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION
:
596 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE
:
599 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG
:
606 g_string_append_printf(ctx
->tsdl
, "%u;\n", level
);
609 /* Event specific context field class */
610 if (ec
->spec_context_fc
) {
612 g_string_append(ctx
->tsdl
, "context := ");
613 append_field_class(ctx
, ec
->spec_context_fc
);
614 g_string_append(ctx
->tsdl
, ";\n");
617 /* Event payload field class */
618 if (ec
->payload_fc
) {
620 g_string_append(ctx
->tsdl
, "fields := ");
621 append_field_class(ctx
, ec
->payload_fc
);
622 g_string_append(ctx
->tsdl
, ";\n");
625 append_end_block_semi_nl_nl(ctx
);
629 void append_stream_class(struct ctx
*ctx
,
630 struct fs_sink_ctf_stream_class
*sc
)
634 /* Default clock class */
635 if (sc
->default_clock_class
) {
637 int64_t offset_seconds
;
638 uint64_t offset_cycles
;
642 g_string_append(ctx
->tsdl
, "clock {\n");
644 BT_ASSERT(sc
->default_clock_class_name
->len
> 0);
646 g_string_append_printf(ctx
->tsdl
, "name = %s;\n",
647 sc
->default_clock_class_name
->str
);
648 descr
= bt_clock_class_get_description(sc
->default_clock_class
);
651 g_string_append(ctx
->tsdl
, "description = ");
652 append_quoted_string(ctx
, descr
);
653 g_string_append(ctx
->tsdl
, ";\n");
657 g_string_append_printf(ctx
->tsdl
, "freq = %" PRIu64
";\n",
658 bt_clock_class_get_frequency(sc
->default_clock_class
));
660 g_string_append_printf(ctx
->tsdl
, "precision = %" PRIu64
";\n",
661 bt_clock_class_get_precision(sc
->default_clock_class
));
662 bt_clock_class_get_offset(sc
->default_clock_class
,
663 &offset_seconds
, &offset_cycles
);
665 g_string_append_printf(ctx
->tsdl
, "offset_s = %" PRId64
";\n",
668 g_string_append_printf(ctx
->tsdl
, "offset = %" PRIu64
";\n",
671 g_string_append(ctx
->tsdl
, "absolute = ");
673 if (bt_clock_class_origin_is_unix_epoch(
674 sc
->default_clock_class
)) {
675 g_string_append(ctx
->tsdl
, "true");
677 g_string_append(ctx
->tsdl
, "false");
680 g_string_append(ctx
->tsdl
, ";\n");
681 uuid
= bt_clock_class_get_uuid(sc
->default_clock_class
);
684 g_string_append(ctx
->tsdl
, "uuid = ");
685 append_uuid(ctx
, uuid
);
686 g_string_append(ctx
->tsdl
, ";\n");
689 /* End clock class */
690 append_end_block_semi_nl_nl(ctx
);
695 g_string_append(ctx
->tsdl
, "stream {\n");
698 /* Stream class properties */
700 g_string_append_printf(ctx
->tsdl
, "id = %" PRIu64
";\n",
701 bt_stream_class_get_id(sc
->ir_sc
));
703 /* Packet context field class */
705 g_string_append(ctx
->tsdl
, "packet.context := struct {\n");
708 append_integer_field_class_from_props(ctx
, 64, 8, false,
709 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
,
710 NULL
, "packet_size", true);
712 append_integer_field_class_from_props(ctx
, 64, 8, false,
713 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
,
714 NULL
, "content_size", true);
716 if (sc
->packets_have_ts_begin
) {
718 append_integer_field_class_from_props(ctx
, 64, 8, false,
719 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
,
720 sc
->default_clock_class_name
->str
,
721 "timestamp_begin", true);
724 if (sc
->packets_have_ts_end
) {
726 append_integer_field_class_from_props(ctx
, 64, 8, false,
727 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
,
728 sc
->default_clock_class_name
->str
,
729 "timestamp_end", true);
732 if (sc
->has_discarded_events
) {
734 append_integer_field_class_from_props(ctx
, 64, 8, false,
735 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
,
736 NULL
, "events_discarded", true);
740 * Unconditionnally write the packet sequence number as, even if
741 * there's no possible discarded packets message, it's still
742 * useful information to have.
745 append_integer_field_class_from_props(ctx
, 64, 8, false,
746 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
,
747 NULL
, "packet_seq_num", true);
749 if (sc
->packet_context_fc
) {
750 append_struct_field_class_members(ctx
,
751 (void *) sc
->packet_context_fc
);
752 fs_sink_ctf_field_class_struct_align_at_least(
753 (void *) sc
->packet_context_fc
, 8);
756 /* End packet context field class */
757 append_end_block(ctx
);
758 g_string_append_printf(ctx
->tsdl
, " align(%u);\n\n",
759 sc
->packet_context_fc
? sc
->packet_context_fc
->alignment
: 8);
761 /* Event header field class */
763 g_string_append(ctx
->tsdl
, "event.header := struct {\n");
766 append_integer_field_class_from_props(ctx
, 64, 8, false,
767 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
,
770 if (sc
->default_clock_class
) {
772 append_integer_field_class_from_props(ctx
, 64, 8, false,
773 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
,
774 sc
->default_clock_class_name
->str
,
778 /* End event header field class */
779 append_end_block(ctx
);
780 g_string_append(ctx
->tsdl
, " align(8);\n");
782 /* Event common context field class */
783 if (sc
->event_common_context_fc
) {
785 g_string_append(ctx
->tsdl
, "event.context := ");
786 append_field_class(ctx
,
787 (void *) sc
->event_common_context_fc
);
788 g_string_append(ctx
->tsdl
, ";\n");
791 /* End stream class */
792 append_end_block_semi_nl_nl(ctx
);
795 for (i
= 0; i
< sc
->event_classes
->len
; i
++) {
796 append_event_class(ctx
, sc
->event_classes
->pdata
[i
]);
801 void translate_trace_ctf_ir_to_tsdl(struct fs_sink_ctf_trace
*trace
,
811 g_string_assign(tsdl
, "/* CTF 1.8 */\n\n");
812 g_string_append(tsdl
, "/* This was generated by a Babeltrace `sink.ctf.fs` component. */\n\n");
816 g_string_append(tsdl
, "trace {\n");
819 /* Trace class properties */
821 g_string_append(tsdl
, "major = 1;\n");
823 g_string_append(tsdl
, "minor = 8;\n");
825 g_string_append(tsdl
, "uuid = ");
826 append_uuid(&ctx
, trace
->uuid
);
827 g_string_append(tsdl
, ";\n");
829 g_string_append(tsdl
, "byte_order = ");
831 if (BYTE_ORDER
== LITTLE_ENDIAN
) {
832 g_string_append(tsdl
, "le");
834 g_string_append(tsdl
, "be");
837 g_string_append(tsdl
, ";\n");
839 /* Packet header field class */
841 g_string_append(tsdl
, "packet.header := struct {\n");
844 append_integer_field_class_from_props(&ctx
, 32, 8, false,
845 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
,
846 NULL
, "magic", true);
848 append_integer_field_class_from_props(&ctx
, 8, 8, false,
849 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
,
850 NULL
, "uuid[16]", true);
852 append_integer_field_class_from_props(&ctx
, 64, 8, false,
853 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
,
854 NULL
, "stream_id", true);
856 append_integer_field_class_from_props(&ctx
, 64, 8, false,
857 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
,
858 NULL
, "stream_instance_id", true);
860 /* End packet header field class */
861 append_end_block(&ctx
);
862 g_string_append(ctx
.tsdl
, " align(8);\n");
864 /* End trace class */
865 append_end_block_semi_nl_nl(&ctx
);
867 /* Trace environment */
868 count
= bt_trace_get_environment_entry_count(trace
->ir_trace
);
871 g_string_append(tsdl
, "env {\n");
874 for (i
= 0; i
< count
; i
++) {
878 bt_trace_borrow_environment_entry_by_index_const(
879 trace
->ir_trace
, i
, &name
, &val
);
881 g_string_append_printf(tsdl
, "%s = ", name
);
883 switch (bt_value_get_type(val
)) {
884 case BT_VALUE_TYPE_SIGNED_INTEGER
:
885 g_string_append_printf(tsdl
, "%" PRId64
,
886 bt_value_integer_signed_get(val
));
888 case BT_VALUE_TYPE_STRING
:
889 append_quoted_string(&ctx
, bt_value_string_get(val
));
894 * translate_trace_trace_ir_to_ctf_ir().
899 g_string_append(tsdl
, ";\n");
902 /* End trace class environment */
903 append_end_block_semi_nl_nl(&ctx
);
906 /* Stream classes and their event classes */
907 for (i
= 0; i
< trace
->stream_classes
->len
; i
++) {
908 append_stream_class(&ctx
, trace
->stream_classes
->pdata
[i
]);