Fix typos
[babeltrace.git] / src / plugins / ctf / fs-sink / translate-ctf-ir-to-tsdl.cpp
CommitLineData
15fe47e0 1/*
0235b0db 2 * SPDX-License-Identifier: MIT
15fe47e0 3 *
0235b0db 4 * Copyright 2019 Philippe Proulx <pproulx@efficios.com>
15fe47e0
PP
5 */
6
c802cacb 7#include <glib.h>
c802cacb 8#include <stdio.h>
c802cacb
SM
9
10#include <babeltrace2/babeltrace.h>
11
578e048b 12#include "common/assert.h"
83ad336c 13#include "compat/endian.h" /* IWYU pragma: keep */
15fe47e0 14
087cd0f5 15#include "fs-sink-ctf-meta.hpp"
c802cacb 16#include "translate-ctf-ir-to-tsdl.hpp"
15fe47e0 17
4164020e
SM
18struct ctx
19{
20 unsigned int indent_level;
21 GString *tsdl;
15fe47e0
PP
22};
23
4164020e 24static inline void append_indent(struct ctx *ctx)
15fe47e0 25{
4164020e 26 unsigned int i;
15fe47e0 27
4164020e
SM
28 for (i = 0; i < ctx->indent_level; i++) {
29 g_string_append_c(ctx->tsdl, '\t');
30 }
15fe47e0
PP
31}
32
4164020e 33static void append_uuid(struct ctx *ctx, bt_uuid uuid)
15fe47e0 34{
4164020e 35 g_string_append_printf(ctx->tsdl, "\"" BT_UUID_FMT "\"", BT_UUID_FMT_VALUES(uuid));
15fe47e0
PP
36}
37
4164020e 38static void append_quoted_string_content(struct ctx *ctx, const char *str)
15fe47e0 39{
4164020e
SM
40 const char *ch;
41
42 for (ch = str; *ch != '\0'; ch++) {
43 unsigned char uch = (unsigned char) *ch;
44
45 if (uch < 32 || uch >= 127) {
46 switch (*ch) {
47 case '\a':
48 g_string_append(ctx->tsdl, "\\a");
49 break;
50 case '\b':
51 g_string_append(ctx->tsdl, "\\b");
52 break;
53 case '\f':
54 g_string_append(ctx->tsdl, "\\f");
55 break;
56 case '\n':
57 g_string_append(ctx->tsdl, "\\n");
58 break;
59 case '\r':
60 g_string_append(ctx->tsdl, "\\r");
61 break;
62 case '\t':
63 g_string_append(ctx->tsdl, "\\t");
64 break;
65 case '\v':
66 g_string_append(ctx->tsdl, "\\v");
67 break;
68 default:
69 g_string_append_printf(ctx->tsdl, "\\x%02x", (unsigned int) uch);
70 break;
71 }
72 } else if (*ch == '"' || *ch == '\\') {
73 g_string_append_c(ctx->tsdl, '\\');
74 g_string_append_c(ctx->tsdl, *ch);
75 } else {
76 g_string_append_c(ctx->tsdl, *ch);
77 }
78 }
15fe47e0
PP
79}
80
4164020e 81static void append_quoted_string(struct ctx *ctx, const char *str)
15fe47e0 82{
4164020e
SM
83 g_string_append_c(ctx->tsdl, '"');
84 append_quoted_string_content(ctx, str);
85 g_string_append_c(ctx->tsdl, '"');
15fe47e0
PP
86}
87
4164020e
SM
88static void append_integer_field_class_from_props(
89 struct ctx *ctx, unsigned int size, unsigned int alignment, bool is_signed,
90 bt_field_class_integer_preferred_display_base disp_base, const char *mapped_clock_class_name,
91 const char *field_name, bool end)
15fe47e0 92{
4164020e
SM
93 g_string_append_printf(ctx->tsdl, "integer { size = %u; align = %u;", size, alignment);
94
95 if (is_signed) {
96 g_string_append(ctx->tsdl, " signed = true;");
97 }
98
99 if (disp_base != BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL) {
100 g_string_append(ctx->tsdl, " base = ");
101
102 switch (disp_base) {
103 case BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY:
104 g_string_append(ctx->tsdl, "b");
105 break;
106 case BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL:
107 g_string_append(ctx->tsdl, "o");
108 break;
109 case BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL:
110 g_string_append(ctx->tsdl, "x");
111 break;
112 default:
113 bt_common_abort();
114 }
115
116 g_string_append_c(ctx->tsdl, ';');
117 }
118
119 if (mapped_clock_class_name) {
120 g_string_append_printf(ctx->tsdl, " map = clock.%s.value;", mapped_clock_class_name);
121 }
122
123 g_string_append(ctx->tsdl, " }");
124
125 if (field_name) {
126 g_string_append_printf(ctx->tsdl, " %s", field_name);
127 }
128
129 if (end) {
130 g_string_append(ctx->tsdl, ";\n");
131 }
15fe47e0
PP
132}
133
4164020e 134static void append_end_block(struct ctx *ctx)
15fe47e0 135{
4164020e
SM
136 ctx->indent_level--;
137 append_indent(ctx);
138 g_string_append(ctx->tsdl, "}");
15fe47e0
PP
139}
140
4164020e 141static void append_end_block_semi_nl(struct ctx *ctx)
15fe47e0 142{
4164020e
SM
143 ctx->indent_level--;
144 append_indent(ctx);
145 g_string_append(ctx->tsdl, "};\n");
15fe47e0
PP
146}
147
4164020e 148static void append_end_block_semi_nl_nl(struct ctx *ctx)
15fe47e0 149{
4164020e
SM
150 append_end_block_semi_nl(ctx);
151 g_string_append_c(ctx->tsdl, '\n');
15fe47e0
PP
152}
153
4164020e
SM
154static void append_bool_field_class(struct ctx *ctx,
155 __attribute__((unused)) struct fs_sink_ctf_field_class_bool *fc)
ecd27ae4 156{
4164020e
SM
157 /*
158 * CTF 1.8 has no boolean field class type, so this component
159 * translates it to an 8-bit unsigned integer field class.
160 */
161 append_integer_field_class_from_props(ctx, fc->base.size, fc->base.base.alignment, false,
162 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL,
163 NULL, NULL, false);
ecd27ae4
PP
164}
165
4164020e
SM
166static void append_bit_array_field_class(struct ctx *ctx,
167 struct fs_sink_ctf_field_class_bit_array *fc)
43a94dc9 168{
4164020e
SM
169 /*
170 * CTF 1.8 has no bit array field class type, so this component
171 * translates it to an unsigned integer field class with an
172 * hexadecimal base.
173 */
174 append_integer_field_class_from_props(ctx, fc->size, fc->base.alignment, false,
175 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL,
176 NULL, NULL, false);
43a94dc9
PP
177}
178
4164020e 179static void append_integer_field_class(struct ctx *ctx, struct fs_sink_ctf_field_class_int *fc)
15fe47e0 180{
4164020e
SM
181 const bt_field_class *ir_fc = fc->base.base.ir_fc;
182 bt_field_class_type type = bt_field_class_get_type(ir_fc);
183 bool is_signed = bt_field_class_type_is(type, BT_FIELD_CLASS_TYPE_SIGNED_INTEGER);
184
185 if (bt_field_class_type_is(type, BT_FIELD_CLASS_TYPE_ENUMERATION)) {
186 g_string_append(ctx->tsdl, "enum : ");
187 }
188
189 append_integer_field_class_from_props(ctx, fc->base.size, fc->base.base.alignment, is_signed,
190 bt_field_class_integer_get_preferred_display_base(ir_fc),
191 NULL, NULL, false);
192
193 if (bt_field_class_type_is(type, BT_FIELD_CLASS_TYPE_ENUMERATION)) {
194 uint64_t i;
195
196 g_string_append(ctx->tsdl, " {\n");
197 ctx->indent_level++;
198
199 for (i = 0; i < bt_field_class_enumeration_get_mapping_count(ir_fc); i++) {
200 const char *label;
201 const bt_field_class_enumeration_mapping *mapping;
202 const bt_field_class_enumeration_unsigned_mapping *u_mapping;
203 const bt_field_class_enumeration_signed_mapping *s_mapping;
204 const bt_integer_range_set *ranges;
205 const bt_integer_range_set_unsigned *u_ranges;
206 const bt_integer_range_set_signed *s_ranges;
207 uint64_t range_count;
208 uint64_t range_i;
209
210 if (is_signed) {
211 s_mapping =
212 bt_field_class_enumeration_signed_borrow_mapping_by_index_const(ir_fc, i);
213 mapping = bt_field_class_enumeration_signed_mapping_as_mapping_const(s_mapping);
214 s_ranges = bt_field_class_enumeration_signed_mapping_borrow_ranges_const(s_mapping);
215 ranges = bt_integer_range_set_signed_as_range_set_const(s_ranges);
216 } else {
217 u_mapping =
218 bt_field_class_enumeration_unsigned_borrow_mapping_by_index_const(ir_fc, i);
219 mapping = bt_field_class_enumeration_unsigned_mapping_as_mapping_const(u_mapping);
220 u_ranges =
221 bt_field_class_enumeration_unsigned_mapping_borrow_ranges_const(u_mapping);
222 ranges = bt_integer_range_set_unsigned_as_range_set_const(u_ranges);
223 }
224
225 label = bt_field_class_enumeration_mapping_get_label(mapping);
226 range_count = bt_integer_range_set_get_range_count(ranges);
227
228 for (range_i = 0; range_i < range_count; range_i++) {
229 append_indent(ctx);
230 g_string_append(ctx->tsdl, "\"");
231 append_quoted_string_content(ctx, label);
232 g_string_append(ctx->tsdl, "\" = ");
233
234 if (is_signed) {
235 const bt_integer_range_signed *range;
236 int64_t lower, upper;
237
238 range =
239 bt_integer_range_set_signed_borrow_range_by_index_const(s_ranges, range_i);
240 lower = bt_integer_range_signed_get_lower(range);
241 upper = bt_integer_range_signed_get_upper(range);
242
243 if (lower == upper) {
244 g_string_append_printf(ctx->tsdl, "%" PRId64, lower);
245 } else {
246 g_string_append_printf(ctx->tsdl, "%" PRId64 " ... %" PRId64, lower, upper);
247 }
248 } else {
249 const bt_integer_range_unsigned *range;
250 uint64_t lower, upper;
251
252 range = bt_integer_range_set_unsigned_borrow_range_by_index_const(u_ranges,
253 range_i);
254 lower = bt_integer_range_unsigned_get_lower(range);
255 upper = bt_integer_range_unsigned_get_upper(range);
256
257 if (lower == upper) {
258 g_string_append_printf(ctx->tsdl, "%" PRIu64, lower);
259 } else {
260 g_string_append_printf(ctx->tsdl, "%" PRIu64 " ... %" PRIu64, lower, upper);
261 }
262 }
263
264 g_string_append(ctx->tsdl, ",\n");
265 }
266 }
267
268 append_end_block(ctx);
269 }
15fe47e0
PP
270}
271
4164020e 272static void append_float_field_class(struct ctx *ctx, struct fs_sink_ctf_field_class_float *fc)
15fe47e0 273{
4164020e
SM
274 unsigned int mant_dig, exp_dig;
275
276 if (bt_field_class_get_type(fc->base.base.ir_fc) == BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL) {
277 mant_dig = 24;
278 exp_dig = 8;
279 } else {
280 mant_dig = 53;
281 exp_dig = 11;
282 }
283
284 g_string_append_printf(ctx->tsdl, "floating_point { mant_dig = %u; exp_dig = %u; align = %u; }",
285 mant_dig, exp_dig, fc->base.base.alignment);
15fe47e0
PP
286}
287
159defec 288static void append_string_field_class(struct ctx *ctx)
15fe47e0 289{
4164020e 290 g_string_append(ctx->tsdl, "string { encoding = UTF8; }");
15fe47e0
PP
291}
292
4164020e 293static void append_field_class(struct ctx *ctx, struct fs_sink_ctf_field_class *fc);
15fe47e0 294
4164020e 295static void append_member(struct ctx *ctx, const char *name, struct fs_sink_ctf_field_class *fc)
15fe47e0 296{
4164020e
SM
297 GString *lengths = NULL;
298 const char *lengths_str = "";
299
300 BT_ASSERT(fc);
301
302 while (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY ||
303 fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE) {
304 if (!lengths) {
305 lengths = g_string_new(NULL);
306 BT_ASSERT(lengths);
307 }
308
309 if (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY) {
310 struct fs_sink_ctf_field_class_array *array_fc = fs_sink_ctf_field_class_as_array(fc);
311
312 g_string_append_printf(lengths, "[%" PRIu64 "]", array_fc->length);
313 fc = array_fc->base.elem_fc;
314 } else {
315 struct fs_sink_ctf_field_class_sequence *seq_fc =
316 fs_sink_ctf_field_class_as_sequence(fc);
317
318 g_string_append_printf(lengths, "[%s]", seq_fc->length_ref->str);
319 fc = seq_fc->base.elem_fc;
320 }
321 }
322
323 append_field_class(ctx, fc);
324
325 if (lengths) {
326 lengths_str = lengths->str;
327 }
328
329 g_string_append_printf(ctx->tsdl, " %s%s;\n", name, lengths_str);
330
331 if (lengths) {
332 g_string_free(lengths, TRUE);
333 }
15fe47e0
PP
334}
335
4164020e
SM
336static void append_struct_field_class_members(struct ctx *ctx,
337 struct fs_sink_ctf_field_class_struct *struct_fc)
15fe47e0 338{
4164020e
SM
339 uint64_t i;
340
341 for (i = 0; i < struct_fc->members->len; i++) {
342 struct fs_sink_ctf_named_field_class *named_fc =
343 fs_sink_ctf_field_class_struct_borrow_member_by_index(struct_fc, i);
344 struct fs_sink_ctf_field_class *fc = named_fc->fc;
345
346 /*
347 * For sequence, option, and variant field classes, if
348 * the length/tag field class is generated before, write
349 * it now before the dependent field class.
350 */
351 if (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE) {
352 struct fs_sink_ctf_field_class_sequence *seq_fc =
353 fs_sink_ctf_field_class_as_sequence(fc);
354
355 if (seq_fc->length_is_before) {
356 append_indent(ctx);
357 append_integer_field_class_from_props(
358 ctx, 32, 8, false, BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, NULL,
359 seq_fc->length_ref->str, true);
360 }
361 } else if (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION) {
362 struct fs_sink_ctf_field_class_option *opt_fc = fs_sink_ctf_field_class_as_option(fc);
363
364 /*
365 * CTF 1.8 does not support the option field
366 * class type. To write something anyway, this
367 * component translates this type to a variant
368 * field class where the options are:
369 *
370 * * An empty structure field class.
371 * * The optional field class itself.
372 *
373 * The "tag" is always generated/before in that
374 * case (an 8-bit unsigned enumeration field
375 * class).
376 */
377 append_indent(ctx);
378 g_string_append(ctx->tsdl, "/* The enumeration and variant field classes "
379 "below were a trace IR option field class. */\n");
380 append_indent(ctx);
381 g_string_append(ctx->tsdl, "enum : ");
382 append_integer_field_class_from_props(
383 ctx, 8, 8, false, BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, NULL, NULL,
384 false);
385 g_string_append(ctx->tsdl, " {\n");
386 ctx->indent_level++;
387 append_indent(ctx);
388 g_string_append(ctx->tsdl, "none = 0,\n");
389 append_indent(ctx);
390 g_string_append(ctx->tsdl, "content = 1,\n");
391 append_end_block(ctx);
392 g_string_append_printf(ctx->tsdl, " %s;\n", opt_fc->tag_ref->str);
393 } else if (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT) {
394 struct fs_sink_ctf_field_class_variant *var_fc = fs_sink_ctf_field_class_as_variant(fc);
395
396 if (var_fc->tag_is_before) {
397 append_indent(ctx);
398 g_string_append(ctx->tsdl, "enum : ");
399 append_integer_field_class_from_props(
400 ctx, 16, 8, false, BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, NULL,
401 NULL, false);
402 g_string_append(ctx->tsdl, " {\n");
403 ctx->indent_level++;
404
405 for (i = 0; i < var_fc->options->len; i++) {
406 struct fs_sink_ctf_named_field_class *option_named_fc =
407 fs_sink_ctf_field_class_variant_borrow_option_by_index(var_fc, i);
408
409 append_indent(ctx);
410 g_string_append_printf(ctx->tsdl, "\"%s\" = %" PRIu64 ",\n",
411 option_named_fc->name->str, i);
412 }
413
414 append_end_block(ctx);
415 g_string_append_printf(ctx->tsdl, " %s;\n", var_fc->tag_ref->str);
416 }
417 } else if (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_BOOL) {
418 append_indent(ctx);
419 g_string_append(
420 ctx->tsdl,
421 "/* The integer field class below was a trace IR boolean field class. */\n");
422 } else if (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_BIT_ARRAY) {
423 append_indent(ctx);
424 g_string_append(
425 ctx->tsdl,
426 "/* The integer field class below was a trace IR bit array field class. */\n");
427 }
428
429 append_indent(ctx);
430 append_member(ctx, named_fc->name->str, fc);
431 }
15fe47e0
PP
432}
433
4164020e 434static void append_struct_field_class(struct ctx *ctx, struct fs_sink_ctf_field_class_struct *fc)
15fe47e0 435{
4164020e
SM
436 g_string_append(ctx->tsdl, "struct {\n");
437 ctx->indent_level++;
438 append_struct_field_class_members(ctx, fc);
439 append_end_block(ctx);
440 g_string_append_printf(ctx->tsdl, " align(%u)", fc->base.alignment);
15fe47e0
PP
441}
442
4164020e
SM
443static void append_option_field_class(struct ctx *ctx,
444 struct fs_sink_ctf_field_class_option *opt_fc)
c25f8e53 445{
4164020e
SM
446 g_string_append_printf(ctx->tsdl, "variant <%s> {\n", opt_fc->tag_ref->str);
447 ctx->indent_level++;
448 append_indent(ctx);
449 g_string_append(ctx->tsdl, "struct { } none;\n");
450 append_indent(ctx);
451 append_member(ctx, "content", opt_fc->content_fc);
452 append_end_block(ctx);
c25f8e53
PP
453}
454
4164020e
SM
455static void append_variant_field_class(struct ctx *ctx,
456 struct fs_sink_ctf_field_class_variant *var_fc)
15fe47e0 457{
4164020e 458 uint64_t i;
15fe47e0 459
4164020e
SM
460 g_string_append_printf(ctx->tsdl, "variant <%s> {\n", var_fc->tag_ref->str);
461 ctx->indent_level++;
15fe47e0 462
4164020e
SM
463 for (i = 0; i < var_fc->options->len; i++) {
464 struct fs_sink_ctf_named_field_class *named_fc =
465 fs_sink_ctf_field_class_variant_borrow_option_by_index(var_fc, i);
15fe47e0 466
4164020e
SM
467 append_indent(ctx);
468 append_member(ctx, named_fc->name->str, named_fc->fc);
469 }
15fe47e0 470
4164020e 471 append_end_block(ctx);
15fe47e0
PP
472}
473
4164020e 474static void append_field_class(struct ctx *ctx, struct fs_sink_ctf_field_class *fc)
15fe47e0 475{
4164020e
SM
476 switch (fc->type) {
477 case FS_SINK_CTF_FIELD_CLASS_TYPE_BOOL:
478 append_bool_field_class(ctx, fs_sink_ctf_field_class_as_bool(fc));
479 break;
480 case FS_SINK_CTF_FIELD_CLASS_TYPE_BIT_ARRAY:
481 append_bit_array_field_class(ctx, fs_sink_ctf_field_class_as_bit_array(fc));
482 break;
483 case FS_SINK_CTF_FIELD_CLASS_TYPE_INT:
484 append_integer_field_class(ctx, fs_sink_ctf_field_class_as_int(fc));
485 break;
486 case FS_SINK_CTF_FIELD_CLASS_TYPE_FLOAT:
487 append_float_field_class(ctx, fs_sink_ctf_field_class_as_float(fc));
488 break;
489 case FS_SINK_CTF_FIELD_CLASS_TYPE_STRING:
159defec 490 append_string_field_class(ctx);
4164020e
SM
491 break;
492 case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT:
493 append_struct_field_class(ctx, fs_sink_ctf_field_class_as_struct(fc));
494 break;
495 case FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION:
496 append_option_field_class(ctx, fs_sink_ctf_field_class_as_option(fc));
497 break;
498 case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT:
499 append_variant_field_class(ctx, fs_sink_ctf_field_class_as_variant(fc));
500 break;
501 default:
502 bt_common_abort();
503 }
15fe47e0
PP
504}
505
4164020e 506static void append_event_class(struct ctx *ctx, struct fs_sink_ctf_event_class *ec)
15fe47e0 507{
4164020e
SM
508 const char *str;
509 bt_event_class_log_level log_level;
510
511 /* Event class */
512 append_indent(ctx);
513 g_string_append(ctx->tsdl, "event {\n");
514 ctx->indent_level++;
515
516 /* Event class properties */
517 append_indent(ctx);
518 g_string_append(ctx->tsdl, "name = ");
519 str = bt_event_class_get_name(ec->ir_ec);
520 if (!str) {
521 str = "unknown";
522 }
523
524 append_quoted_string(ctx, str);
525 g_string_append(ctx->tsdl, ";\n");
526 append_indent(ctx);
527 g_string_append_printf(ctx->tsdl, "stream_id = %" PRIu64 ";\n",
528 bt_stream_class_get_id(ec->sc->ir_sc));
529 append_indent(ctx);
530 g_string_append_printf(ctx->tsdl, "id = %" PRIu64 ";\n", bt_event_class_get_id(ec->ir_ec));
531
532 str = bt_event_class_get_emf_uri(ec->ir_ec);
533 if (str) {
534 append_indent(ctx);
535 g_string_append(ctx->tsdl, "model.emf.uri = ");
536 append_quoted_string(ctx, str);
537 g_string_append(ctx->tsdl, ";\n");
538 }
539
540 if (bt_event_class_get_log_level(ec->ir_ec, &log_level) == BT_PROPERTY_AVAILABILITY_AVAILABLE) {
541 unsigned int level;
542
543 append_indent(ctx);
544 g_string_append(ctx->tsdl, "loglevel = ");
545
546 switch (log_level) {
547 case BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY:
548 level = 0;
549 break;
550 case BT_EVENT_CLASS_LOG_LEVEL_ALERT:
551 level = 1;
552 break;
553 case BT_EVENT_CLASS_LOG_LEVEL_CRITICAL:
554 level = 2;
555 break;
556 case BT_EVENT_CLASS_LOG_LEVEL_ERROR:
557 level = 3;
558 break;
559 case BT_EVENT_CLASS_LOG_LEVEL_WARNING:
560 level = 4;
561 break;
562 case BT_EVENT_CLASS_LOG_LEVEL_NOTICE:
563 level = 5;
564 break;
565 case BT_EVENT_CLASS_LOG_LEVEL_INFO:
566 level = 6;
567 break;
568 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM:
569 level = 7;
570 break;
571 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM:
572 level = 8;
573 break;
574 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS:
575 level = 9;
576 break;
577 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE:
578 level = 10;
579 break;
580 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT:
581 level = 11;
582 break;
583 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION:
584 level = 12;
585 break;
586 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE:
587 level = 13;
588 break;
589 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG:
590 level = 14;
591 break;
592 default:
593 bt_common_abort();
594 }
595
596 g_string_append_printf(ctx->tsdl, "%u;\n", level);
597 }
598
599 /* Event specific context field class */
600 if (ec->spec_context_fc) {
601 append_indent(ctx);
602 g_string_append(ctx->tsdl, "context := ");
603 append_field_class(ctx, ec->spec_context_fc);
604 g_string_append(ctx->tsdl, ";\n");
605 }
606
607 /* Event payload field class */
608 if (ec->payload_fc) {
609 append_indent(ctx);
610 g_string_append(ctx->tsdl, "fields := ");
611 append_field_class(ctx, ec->payload_fc);
612 g_string_append(ctx->tsdl, ";\n");
613 }
614
615 append_end_block_semi_nl_nl(ctx);
15fe47e0
PP
616}
617
4164020e 618static void append_stream_class(struct ctx *ctx, struct fs_sink_ctf_stream_class *sc)
15fe47e0 619{
4164020e
SM
620 uint64_t i;
621
622 /* Default clock class */
623 if (sc->default_clock_class) {
624 const char *descr;
625 int64_t offset_seconds;
626 uint64_t offset_cycles;
627 bt_uuid uuid;
628
629 append_indent(ctx);
630 g_string_append(ctx->tsdl, "clock {\n");
631 ctx->indent_level++;
632 BT_ASSERT(sc->default_clock_class_name->len > 0);
633 append_indent(ctx);
634 g_string_append_printf(ctx->tsdl, "name = %s;\n", sc->default_clock_class_name->str);
635 descr = bt_clock_class_get_description(sc->default_clock_class);
636 if (descr) {
637 append_indent(ctx);
638 g_string_append(ctx->tsdl, "description = ");
639 append_quoted_string(ctx, descr);
640 g_string_append(ctx->tsdl, ";\n");
641 }
642
643 append_indent(ctx);
644 g_string_append_printf(ctx->tsdl, "freq = %" PRIu64 ";\n",
645 bt_clock_class_get_frequency(sc->default_clock_class));
646 append_indent(ctx);
647 g_string_append_printf(ctx->tsdl, "precision = %" PRIu64 ";\n",
648 bt_clock_class_get_precision(sc->default_clock_class));
649 bt_clock_class_get_offset(sc->default_clock_class, &offset_seconds, &offset_cycles);
650 append_indent(ctx);
651 g_string_append_printf(ctx->tsdl, "offset_s = %" PRId64 ";\n", offset_seconds);
652 append_indent(ctx);
653 g_string_append_printf(ctx->tsdl, "offset = %" PRIu64 ";\n", offset_cycles);
654 append_indent(ctx);
655 g_string_append(ctx->tsdl, "absolute = ");
656
657 if (bt_clock_class_origin_is_unix_epoch(sc->default_clock_class)) {
658 g_string_append(ctx->tsdl, "true");
659 } else {
660 g_string_append(ctx->tsdl, "false");
661 }
662
663 g_string_append(ctx->tsdl, ";\n");
664 uuid = bt_clock_class_get_uuid(sc->default_clock_class);
665 if (uuid) {
666 append_indent(ctx);
667 g_string_append(ctx->tsdl, "uuid = ");
668 append_uuid(ctx, uuid);
669 g_string_append(ctx->tsdl, ";\n");
670 }
671
672 /* End clock class */
673 append_end_block_semi_nl_nl(ctx);
674 }
675
676 /* Stream class */
677 append_indent(ctx);
678 g_string_append(ctx->tsdl, "stream {\n");
679 ctx->indent_level++;
680
681 /* Stream class properties */
682 append_indent(ctx);
683 g_string_append_printf(ctx->tsdl, "id = %" PRIu64 ";\n", bt_stream_class_get_id(sc->ir_sc));
684
685 /* Packet context field class */
686 append_indent(ctx);
687 g_string_append(ctx->tsdl, "packet.context := struct {\n");
688 ctx->indent_level++;
689 append_indent(ctx);
690 append_integer_field_class_from_props(ctx, 64, 8, false,
691 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL,
692 NULL, "packet_size", true);
693 append_indent(ctx);
694 append_integer_field_class_from_props(ctx, 64, 8, false,
695 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL,
696 NULL, "content_size", true);
697
698 if (sc->packets_have_ts_begin) {
699 append_indent(ctx);
700 append_integer_field_class_from_props(
701 ctx, 64, 8, false, BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL,
702 sc->default_clock_class_name->str, "timestamp_begin", true);
703 }
704
705 if (sc->packets_have_ts_end) {
706 append_indent(ctx);
707 append_integer_field_class_from_props(
708 ctx, 64, 8, false, BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL,
709 sc->default_clock_class_name->str, "timestamp_end", true);
710 }
711
712 if (sc->has_discarded_events) {
713 append_indent(ctx);
714 append_integer_field_class_from_props(ctx, 64, 8, false,
715 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL,
716 NULL, "events_discarded", true);
717 }
718
719 /*
e7401568 720 * Unconditionally write the packet sequence number as, even if
4164020e
SM
721 * there's no possible discarded packets message, it's still
722 * useful information to have.
723 */
724 append_indent(ctx);
725 append_integer_field_class_from_props(ctx, 64, 8, false,
726 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL,
727 NULL, "packet_seq_num", true);
728
729 if (sc->packet_context_fc) {
730 append_struct_field_class_members(ctx,
731 fs_sink_ctf_field_class_as_struct(sc->packet_context_fc));
732 fs_sink_ctf_field_class_struct_align_at_least(
733 fs_sink_ctf_field_class_as_struct(sc->packet_context_fc), 8);
734 }
735
736 /* End packet context field class */
737 append_end_block(ctx);
738 g_string_append_printf(ctx->tsdl, " align(%u);\n\n",
739 sc->packet_context_fc ? sc->packet_context_fc->alignment : 8);
740
741 /* Event header field class */
742 append_indent(ctx);
743 g_string_append(ctx->tsdl, "event.header := struct {\n");
744 ctx->indent_level++;
745 append_indent(ctx);
746 append_integer_field_class_from_props(
747 ctx, 64, 8, false, BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, NULL, "id", true);
748
749 if (sc->default_clock_class) {
750 append_indent(ctx);
751 append_integer_field_class_from_props(ctx, 64, 8, false,
752 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL,
753 sc->default_clock_class_name->str, "timestamp", true);
754 }
755
756 /* End event header field class */
757 append_end_block(ctx);
758 g_string_append(ctx->tsdl, " align(8);\n");
759
760 /* Event common context field class */
761 if (sc->event_common_context_fc) {
762 append_indent(ctx);
763 g_string_append(ctx->tsdl, "event.context := ");
764 append_field_class(ctx, sc->event_common_context_fc);
765 g_string_append(ctx->tsdl, ";\n");
766 }
767
768 /* End stream class */
769 append_end_block_semi_nl_nl(ctx);
770
771 /* Event classes */
772 for (i = 0; i < sc->event_classes->len; i++) {
773 append_event_class(ctx, (fs_sink_ctf_event_class *) sc->event_classes->pdata[i]);
774 }
15fe47e0
PP
775}
776
4164020e 777void translate_trace_ctf_ir_to_tsdl(struct fs_sink_ctf_trace *trace, GString *tsdl)
15fe47e0 778{
4164020e
SM
779 struct ctx ctx = {
780 .indent_level = 0,
781 .tsdl = tsdl,
782 };
783 uint64_t i;
784 uint64_t count;
785
786 g_string_assign(tsdl, "/* CTF 1.8 */\n\n");
787 g_string_append(tsdl, "/* This was generated by a Babeltrace `sink.ctf.fs` component. */\n\n");
788
789 /* Trace class */
790 append_indent(&ctx);
791 g_string_append(tsdl, "trace {\n");
792 ctx.indent_level++;
793
794 /* Trace class properties */
795 append_indent(&ctx);
796 g_string_append(tsdl, "major = 1;\n");
797 append_indent(&ctx);
798 g_string_append(tsdl, "minor = 8;\n");
799 append_indent(&ctx);
800 g_string_append(tsdl, "uuid = ");
801 append_uuid(&ctx, trace->uuid);
802 g_string_append(tsdl, ";\n");
803 append_indent(&ctx);
804 g_string_append(tsdl, "byte_order = ");
805
806 if (BYTE_ORDER == LITTLE_ENDIAN) {
807 g_string_append(tsdl, "le");
808 } else {
809 g_string_append(tsdl, "be");
810 }
811
812 g_string_append(tsdl, ";\n");
813
814 /* Packet header field class */
815 append_indent(&ctx);
816 g_string_append(tsdl, "packet.header := struct {\n");
817 ctx.indent_level++;
818 append_indent(&ctx);
819 append_integer_field_class_from_props(&ctx, 32, 8, false,
820 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL,
821 NULL, "magic", true);
822 append_indent(&ctx);
823 append_integer_field_class_from_props(&ctx, 8, 8, false,
824 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL,
825 NULL, "uuid[16]", true);
826 append_indent(&ctx);
827 append_integer_field_class_from_props(&ctx, 64, 8, false,
828 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL,
829 NULL, "stream_id", true);
830 append_indent(&ctx);
831 append_integer_field_class_from_props(&ctx, 64, 8, false,
832 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL,
833 NULL, "stream_instance_id", true);
834
835 /* End packet header field class */
836 append_end_block(&ctx);
837 g_string_append(ctx.tsdl, " align(8);\n");
838
839 /* End trace class */
840 append_end_block_semi_nl_nl(&ctx);
841
842 /* Trace environment */
843 count = bt_trace_get_environment_entry_count(trace->ir_trace);
844 if (count > 0) {
845 append_indent(&ctx);
846 g_string_append(tsdl, "env {\n");
847 ctx.indent_level++;
848
849 for (i = 0; i < count; i++) {
850 const char *name;
851 const bt_value *val;
852
853 bt_trace_borrow_environment_entry_by_index_const(trace->ir_trace, i, &name, &val);
854 append_indent(&ctx);
855 g_string_append_printf(tsdl, "%s = ", name);
856
857 switch (bt_value_get_type(val)) {
858 case BT_VALUE_TYPE_SIGNED_INTEGER:
859 g_string_append_printf(tsdl, "%" PRId64, bt_value_integer_signed_get(val));
860 break;
861 case BT_VALUE_TYPE_STRING:
862 append_quoted_string(&ctx, bt_value_string_get(val));
863 break;
864 default:
865 /*
866 * This is checked in
867 * translate_trace_trace_ir_to_ctf_ir().
868 */
869 bt_common_abort();
870 }
871
872 g_string_append(tsdl, ";\n");
873 }
874
875 /* End trace class environment */
876 append_end_block_semi_nl_nl(&ctx);
877 }
878
879 /* Stream classes and their event classes */
880 for (i = 0; i < trace->stream_classes->len; i++) {
881 append_stream_class(&ctx, (fs_sink_ctf_stream_class *) trace->stream_classes->pdata[i]);
882 }
15fe47e0 883}
This page took 0.118852 seconds and 4 git commands to generate.