Trace IR and notification APIs: split into private and public APIs
[babeltrace.git] / plugins / ctf / common / metadata / ctf-meta-translate.c
1 /*
2 * Copyright 2018 - Philippe Proulx <pproulx@efficios.com>
3 *
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:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 */
14
15 #define BT_LOG_TAG "PLUGIN-CTF-METADATA-META-TRANSLATE"
16 #include "logging.h"
17
18 #include <babeltrace/babeltrace.h>
19 #include <babeltrace/babeltrace-internal.h>
20 #include <babeltrace/assert-internal.h>
21 #include <glib.h>
22 #include <stdint.h>
23 #include <string.h>
24 #include <inttypes.h>
25
26 #include "ctf-meta-visitors.h"
27
28 static inline
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);
33
34 static inline
35 void ctf_field_class_int_set_props(struct ctf_field_class_int *fc,
36 struct bt_private_field_class *ir_fc)
37 {
38 int ret;
39
40 ret = bt_private_field_class_integer_set_field_value_range(ir_fc,
41 fc->base.size);
42 BT_ASSERT(ret == 0);
43 ret = bt_private_field_class_integer_set_preferred_display_base(ir_fc,
44 fc->disp_base);
45 BT_ASSERT(ret == 0);
46 }
47
48 static inline
49 struct bt_private_field_class *ctf_field_class_int_to_ir(
50 struct ctf_field_class_int *fc)
51 {
52 struct bt_private_field_class *ir_fc;
53
54 if (fc->is_signed) {
55 ir_fc = bt_private_field_class_signed_integer_create();
56 } else {
57 ir_fc = bt_private_field_class_unsigned_integer_create();
58 }
59
60 BT_ASSERT(ir_fc);
61 ctf_field_class_int_set_props(fc, ir_fc);
62 return ir_fc;
63 }
64
65 static inline
66 struct bt_private_field_class *ctf_field_class_enum_to_ir(
67 struct ctf_field_class_enum *fc)
68 {
69 int ret;
70 struct bt_private_field_class *ir_fc;
71 uint64_t i;
72
73 if (fc->base.is_signed) {
74 ir_fc = bt_private_field_class_signed_enumeration_create();
75 } else {
76 ir_fc = bt_private_field_class_unsigned_enumeration_create();
77 }
78
79 BT_ASSERT(ir_fc);
80 ctf_field_class_int_set_props((void *) fc, ir_fc);
81
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);
85
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);
90 } else {
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);
94 }
95
96 BT_ASSERT(ret == 0);
97 }
98
99 return ir_fc;
100 }
101
102 static inline
103 struct bt_private_field_class *ctf_field_class_float_to_ir(
104 struct ctf_field_class_float *fc)
105 {
106 struct bt_private_field_class *ir_fc;
107 int ret;
108
109 ir_fc = bt_private_field_class_real_create();
110 BT_ASSERT(ir_fc);
111
112 if (fc->base.size == 32) {
113 ret = bt_private_field_class_real_set_is_single_precision(ir_fc,
114 BT_TRUE);
115 BT_ASSERT(ret == 0);
116 }
117
118 return ir_fc;
119 }
120
121 static inline
122 struct bt_private_field_class *ctf_field_class_string_to_ir(
123 struct ctf_field_class_string *fc)
124 {
125 struct bt_private_field_class *ir_fc =
126 bt_private_field_class_string_create();
127
128 BT_ASSERT(ir_fc);
129 return ir_fc;
130 }
131
132 static inline
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)
138 {
139 int ret;
140 struct bt_private_field_class *ir_fc =
141 bt_private_field_class_structure_create();
142 uint64_t i;
143
144 BT_ASSERT(ir_fc);
145
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;
150
151 if (!named_fc->fc->in_ir) {
152 continue;
153 }
154
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_private_member(
158 ir_fc, named_fc->name->str, member_ir_fc);
159 BT_ASSERT(ret == 0);
160 bt_object_put_ref(member_ir_fc);
161 }
162
163 return ir_fc;
164 }
165
166 static inline
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)
172 {
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);
176
177 BT_ASSERT(fc);
178
179 if (fc->in_ir) {
180 ir_fc = fc->ir_fc;
181 }
182
183 return ir_fc;
184 }
185
186 static inline
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)
192 {
193 int ret;
194 struct bt_private_field_class *ir_fc =
195 bt_private_field_class_variant_create();
196 uint64_t i;
197
198 BT_ASSERT(ir_fc);
199 ret = bt_private_field_class_variant_set_selector_private_field_class(
200 ir_fc, borrow_ir_ft_from_field_path(&fc->tag_path, tc, sc, ec));
201 BT_ASSERT(ret == 0);
202
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;
207
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);
213 BT_ASSERT(ret == 0);
214 bt_object_put_ref(option_ir_fc);
215 }
216
217 return ir_fc;
218 }
219
220 static inline
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)
226 {
227 struct bt_private_field_class *ir_fc;
228 struct bt_private_field_class *elem_ir_fc;
229
230 if (fc->base.is_text) {
231 ir_fc = bt_private_field_class_string_create();
232 BT_ASSERT(ir_fc);
233 goto end;
234 }
235
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,
239 fc->length);
240 BT_ASSERT(ir_fc);
241 bt_object_put_ref(elem_ir_fc);
242
243 end:
244 return ir_fc;
245 }
246
247 static inline
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)
253 {
254 int ret;
255 struct bt_private_field_class *ir_fc;
256 struct bt_private_field_class *elem_ir_fc;
257
258 if (fc->base.is_text) {
259 ir_fc = bt_private_field_class_string_create();
260 BT_ASSERT(ir_fc);
261 goto end;
262 }
263
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);
267 BT_ASSERT(ir_fc);
268 bt_object_put_ref(elem_ir_fc);
269 BT_ASSERT(ir_fc);
270 ret = bt_private_field_class_dynamic_array_set_length_private_field_class(
271 ir_fc,
272 borrow_ir_ft_from_field_path(&fc->length_path, tc, sc, ec));
273 BT_ASSERT(ret == 0);
274
275 end:
276 return ir_fc;
277 }
278
279 static inline
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)
284 {
285 struct bt_private_field_class *ir_fc = NULL;
286
287 BT_ASSERT(fc);
288 BT_ASSERT(fc->in_ir);
289
290 switch (fc->type) {
291 case CTF_FIELD_CLASS_TYPE_INT:
292 ir_fc = ctf_field_class_int_to_ir((void *) fc);
293 break;
294 case CTF_FIELD_CLASS_TYPE_ENUM:
295 ir_fc = ctf_field_class_enum_to_ir((void *) fc);
296 break;
297 case CTF_FIELD_CLASS_TYPE_FLOAT:
298 ir_fc = ctf_field_class_float_to_ir((void *) fc);
299 break;
300 case CTF_FIELD_CLASS_TYPE_STRING:
301 ir_fc = ctf_field_class_string_to_ir((void *) fc);
302 break;
303 case CTF_FIELD_CLASS_TYPE_STRUCT:
304 ir_fc = ctf_field_class_struct_to_ir((void *) fc, tc, sc, ec);
305 break;
306 case CTF_FIELD_CLASS_TYPE_ARRAY:
307 ir_fc = ctf_field_class_array_to_ir((void *) fc, tc, sc, ec);
308 break;
309 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
310 ir_fc = ctf_field_class_sequence_to_ir((void *) fc, tc, sc, ec);
311 break;
312 case CTF_FIELD_CLASS_TYPE_VARIANT:
313 ir_fc = ctf_field_class_variant_to_ir((void *) fc, tc, sc, ec);
314 break;
315 default:
316 abort();
317 }
318
319 fc->ir_fc = ir_fc;
320 return ir_fc;
321 }
322
323 static inline
324 bool ctf_field_class_struct_has_immediate_member_in_ir(
325 struct ctf_field_class_struct *fc)
326 {
327 uint64_t i;
328 bool has_immediate_member_in_ir = false;
329
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);
333
334 if (named_fc->fc->in_ir) {
335 has_immediate_member_in_ir = true;
336 goto end;
337 }
338 }
339
340 end:
341 return has_immediate_member_in_ir;
342 }
343
344 static inline
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)
349 {
350 struct bt_private_field_class *ir_fc = NULL;
351
352 if (!fc) {
353 goto end;
354 }
355
356 BT_ASSERT(fc->type == CTF_FIELD_CLASS_TYPE_STRUCT);
357
358 if (!ctf_field_class_struct_has_immediate_member_in_ir((void *) fc)) {
359 /*
360 * Nothing for IR in this scope: typical for packet
361 * header, packet context, and event header.
362 */
363 goto end;
364 }
365
366 ir_fc = ctf_field_class_to_ir(fc, tc, sc, ec);
367
368 end:
369 return ir_fc;
370 }
371
372 static inline
373 struct ctf_field_class_int *borrow_named_int_field_class(
374 struct ctf_field_class_struct *struct_fc, const char *name)
375 {
376 struct ctf_named_field_class *named_fc = NULL;
377 struct ctf_field_class_int *int_fc = NULL;
378
379 if (!struct_fc) {
380 goto end;
381 }
382
383 named_fc = ctf_field_class_struct_borrow_member_by_name(struct_fc, name);
384 if (!named_fc) {
385 goto end;
386 }
387
388 if (named_fc->fc->type != CTF_FIELD_CLASS_TYPE_INT &&
389 named_fc->fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
390 goto end;
391 }
392
393 int_fc = (void *) named_fc->fc;
394
395 end:
396 return int_fc;
397 }
398
399 static inline
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)
403 {
404 int ret;
405 struct bt_private_event_class *ir_ec = NULL;
406
407 if (ec->is_translated) {
408 ir_ec = bt_private_stream_class_borrow_private_event_class_by_id(
409 ir_sc, ec->id);
410 BT_ASSERT(ir_ec);
411 goto end;
412 }
413
414 ir_ec = bt_private_event_class_create_with_id(ir_sc, ec->id);
415 BT_ASSERT(ir_ec);
416 bt_object_put_ref(ir_ec);
417
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);
421
422 if (ir_fc) {
423 ret = bt_private_event_class_set_specific_context_private_field_class(
424 ir_ec, ir_fc);
425 BT_ASSERT(ret == 0);
426 bt_object_put_ref(ir_fc);
427 }
428 }
429
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);
433
434 if (ir_fc) {
435 ret = bt_private_event_class_set_payload_private_field_class(ir_ec,
436 ir_fc);
437 BT_ASSERT(ret == 0);
438 bt_object_put_ref(ir_fc);
439 }
440 }
441
442 if (ec->name->len > 0) {
443 ret = bt_private_event_class_set_name(ir_ec, ec->name->str);
444 BT_ASSERT(ret == 0);
445 }
446
447 if (ec->emf_uri->len > 0) {
448 ret = bt_private_event_class_set_emf_uri(ir_ec, ec->emf_uri->str);
449 BT_ASSERT(ret == 0);
450 }
451
452 if (ec->log_level != -1) {
453 ret = bt_private_event_class_set_log_level(ir_ec, ec->log_level);
454 BT_ASSERT(ret == 0);
455 }
456
457 ec->is_translated = true;
458 ec->ir_ec = ir_ec;
459
460 end:
461 return ir_ec;
462 }
463
464
465 static inline
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)
468 {
469 int ret;
470 struct bt_private_stream_class *ir_sc = NULL;
471 struct ctf_field_class_int *int_fc;
472
473 if (sc->is_translated) {
474 ir_sc = bt_private_trace_borrow_private_stream_class_by_id(
475 ir_trace, sc->id);
476 BT_ASSERT(ir_sc);
477 goto end;
478 }
479
480 ir_sc = bt_private_stream_class_create_with_id(ir_trace, sc->id);
481 BT_ASSERT(ir_sc);
482 bt_object_put_ref(ir_sc);
483
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);
487
488 if (ir_fc) {
489 ret = bt_private_stream_class_set_packet_context_private_field_class(
490 ir_sc, ir_fc);
491 BT_ASSERT(ret == 0);
492 bt_object_put_ref(ir_fc);
493 }
494 }
495
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);
499
500 if (ir_fc) {
501 ret = bt_private_stream_class_set_event_header_private_field_class(
502 ir_sc, ir_fc);
503 BT_ASSERT(ret == 0);
504 bt_object_put_ref(ir_fc);
505 }
506 }
507
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);
511
512 if (ir_fc) {
513 ret = bt_private_stream_class_set_event_common_context_private_field_class(
514 ir_sc, ir_fc);
515 BT_ASSERT(ret == 0);
516 bt_object_put_ref(ir_fc);
517 }
518 }
519
520 ret = bt_private_stream_class_set_assigns_automatic_event_class_id(ir_sc,
521 BT_FALSE);
522 BT_ASSERT(ret == 0);
523 ret = bt_private_stream_class_set_assigns_automatic_stream_id(ir_sc, BT_FALSE);
524 BT_ASSERT(ret == 0);
525
526 if (sc->default_clock_class) {
527 ret = bt_private_stream_class_set_default_clock_class(ir_sc,
528 bt_clock_class_borrow_from_private(sc->default_clock_class));
529 BT_ASSERT(ret == 0);
530 }
531
532 int_fc = borrow_named_int_field_class((void *) sc->packet_context_fc,
533 "events_discarded");
534 if (int_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(
537 ir_sc, BT_TRUE);
538 BT_ASSERT(ret == 0);
539 }
540 }
541
542 int_fc = borrow_named_int_field_class((void *) sc->packet_context_fc,
543 "packet_seq_num");
544 if (int_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(
547 ir_sc, BT_TRUE);
548 BT_ASSERT(ret == 0);
549 }
550 }
551
552 int_fc = borrow_named_int_field_class((void *) sc->packet_context_fc,
553 "timestamp_begin");
554 if (int_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(
557 ir_sc, BT_TRUE);
558 BT_ASSERT(ret == 0);
559 }
560 }
561
562 int_fc = borrow_named_int_field_class((void *) sc->packet_context_fc,
563 "timestamp_end");
564 if (int_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(
567 ir_sc, BT_TRUE);
568 BT_ASSERT(ret == 0);
569 }
570 }
571
572 sc->is_translated = true;
573 sc->ir_sc = ir_sc;
574
575 end:
576 return ir_sc;
577 }
578
579 static inline
580 int ctf_trace_class_to_ir(struct bt_private_trace *ir_trace,
581 struct ctf_trace_class *tc)
582 {
583 int ret = 0;
584 uint64_t i;
585
586 if (tc->is_translated) {
587 goto end;
588 }
589
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);
593
594 if (ir_fc) {
595 ret = bt_private_trace_set_packet_header_private_field_class(
596 ir_trace, ir_fc);
597 BT_ASSERT(ret == 0);
598 bt_object_put_ref(ir_fc);
599 }
600 }
601
602 if (tc->name->len > 0) {
603 ret = bt_private_trace_set_name(ir_trace, tc->name->str);
604 if (ret) {
605 goto end;
606 }
607 }
608
609 if (tc->is_uuid_set) {
610 ret = bt_private_trace_set_uuid(ir_trace, tc->uuid);
611 if (ret) {
612 goto end;
613 }
614 }
615
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);
619
620 switch (env_entry->type) {
621 case CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT:
622 ret = bt_private_trace_set_private_environment_entry_integer(
623 ir_trace, env_entry->name->str,
624 env_entry->value.i);
625 break;
626 case CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR:
627 ret = bt_private_trace_set_private_environment_entry_string(
628 ir_trace, env_entry->name->str,
629 env_entry->value.str->str);
630 break;
631 default:
632 abort();
633 }
634
635 if (ret) {
636 goto end;
637 }
638 }
639
640 ret = bt_private_trace_set_assigns_automatic_stream_class_id(ir_trace,
641 BT_FALSE);
642 if (ret) {
643 goto end;
644 }
645
646 tc->is_translated = true;
647 tc->ir_tc = ir_trace;
648
649 end:
650 return ret;
651 }
652
653 BT_HIDDEN
654 int ctf_trace_class_translate(struct bt_private_trace *ir_trace,
655 struct ctf_trace_class *tc)
656 {
657 int ret = 0;
658 uint64_t i;
659
660 ret = ctf_trace_class_to_ir(ir_trace, tc);
661 if (ret) {
662 goto end;
663 }
664
665 for (i = 0; i < tc->stream_classes->len; i++) {
666 uint64_t j;
667 struct ctf_stream_class *sc = tc->stream_classes->pdata[i];
668 struct bt_private_stream_class *ir_sc;
669
670 ir_sc = ctf_stream_class_to_ir(sc, ir_trace, tc);
671 if (!ir_sc) {
672 ret = -1;
673 goto end;
674 }
675
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;
679
680 ir_ec = ctf_event_class_to_ir(ec, ir_sc, tc, sc);
681 if (!ir_ec) {
682 ret = -1;
683 goto end;
684 }
685 }
686 }
687
688 end:
689 return ret;
690 }
This page took 0.043715 seconds and 4 git commands to generate.