4 * Babeltrace CTF Text Output Plugin Event Printing
6 * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
7 * Copyright 2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
9 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 #include <babeltrace/ctf-ir/event.h>
31 #include <babeltrace/ctf-ir/event-class.h>
32 #include <babeltrace/ctf-ir/packet.h>
33 #include <babeltrace/ctf-ir/stream.h>
34 #include <babeltrace/ctf-ir/stream-class.h>
35 #include <babeltrace/ctf-ir/clock-class.h>
36 #include <babeltrace/ctf-ir/field-types.h>
37 #include <babeltrace/ctf-ir/fields.h>
38 #include <babeltrace/ctf-ir/trace.h>
39 #include <babeltrace/bitfield.h>
43 #define NSEC_PER_SEC 1000000000LL
46 const char *rem_(const char *str
)
55 int64_t real_timestamp
; /* Relative to UNIX epoch. */
56 uint64_t clock_value
; /* In cycles. */
60 enum bt_component_status
print_field(struct text_component
*text
,
61 struct bt_ctf_field
*field
, bool print_names
);
64 void print_timestamp_cycles(struct text_component
*text
,
65 struct bt_ctf_clock_class
*clock_class
,
66 struct bt_ctf_event
*event
)
69 struct bt_ctf_clock_value
*clock_value
;
72 clock_value
= bt_ctf_event_get_clock_value(event
, clock_class
);
74 fputs("????????????????????", text
->out
);
78 ret
= bt_ctf_clock_value_get_value(clock_value
, &cycles
);
81 fprintf(text
->out
, "Error");
84 fprintf(text
->out
, "%020" PRIu64
, cycles
);
86 if (text
->last_cycles_timestamp
!= -1ULL) {
87 text
->delta_cycles
= cycles
- text
->last_cycles_timestamp
;
89 text
->last_cycles_timestamp
= cycles
;
93 void print_timestamp_wall(struct text_component
*text
,
94 struct bt_ctf_clock_class
*clock_class
,
95 struct bt_ctf_event
*event
)
98 struct bt_ctf_clock_value
*clock_value
;
99 int64_t ts_nsec
= 0; /* add configurable offset */
100 int64_t ts_sec
= 0; /* add configurable offset */
101 uint64_t ts_sec_abs
, ts_nsec_abs
;
104 clock_value
= bt_ctf_event_get_clock_value(event
, clock_class
);
106 fputs("??:??:??.?????????", text
->out
);
110 ret
= bt_ctf_clock_value_get_value_ns_from_epoch(clock_value
, &ts_nsec
);
113 fprintf(text
->out
, "Error");
117 if (text
->last_real_timestamp
!= -1ULL) {
118 text
->delta_real_timestamp
= ts_nsec
- text
->last_real_timestamp
;
120 text
->last_real_timestamp
= ts_nsec
;
122 ts_sec
+= ts_nsec
/ NSEC_PER_SEC
;
123 ts_nsec
= ts_nsec
% NSEC_PER_SEC
;
124 if (ts_sec
>= 0 && ts_nsec
>= 0) {
127 ts_nsec_abs
= ts_nsec
;
128 } else if (ts_sec
> 0 && ts_nsec
< 0) {
130 ts_sec_abs
= ts_sec
- 1;
131 ts_nsec_abs
= NSEC_PER_SEC
+ ts_nsec
;
132 } else if (ts_sec
== 0 && ts_nsec
< 0) {
135 ts_nsec_abs
= -ts_nsec
;
136 } else if (ts_sec
< 0 && ts_nsec
> 0) {
138 ts_sec_abs
= -(ts_sec
+ 1);
139 ts_nsec_abs
= NSEC_PER_SEC
- ts_nsec
;
140 } else if (ts_sec
< 0 && ts_nsec
== 0) {
142 ts_sec_abs
= -ts_sec
;
143 ts_nsec_abs
= ts_nsec
;
144 } else { /* (ts_sec < 0 && ts_nsec < 0) */
146 ts_sec_abs
= -ts_sec
;
147 ts_nsec_abs
= -ts_nsec
;
150 if (!text
->options
.clock_seconds
) {
152 time_t time_s
= (time_t) ts_sec_abs
;
155 fprintf(stderr
, "[warning] Fallback to [sec.ns] to print negative time value. Use --clock-seconds.\n");
159 if (!text
->options
.clock_gmt
) {
162 res
= localtime_r(&time_s
, &tm
);
164 fprintf(stderr
, "[warning] Unable to get localtime.\n");
170 res
= gmtime_r(&time_s
, &tm
);
172 fprintf(stderr
, "[warning] Unable to get gmtime.\n");
176 if (text
->options
.clock_date
) {
180 /* Print date and time */
181 res
= strftime(timestr
, sizeof(timestr
),
184 fprintf(stderr
, "[warning] Unable to print ascii time.\n");
187 fprintf(text
->out
, "%s", timestr
);
189 /* Print time in HH:MM:SS.ns */
190 fprintf(text
->out
, "%02d:%02d:%02d.%09" PRIu64
,
191 tm
.tm_hour
, tm
.tm_min
, tm
.tm_sec
, ts_nsec_abs
);
195 fprintf(text
->out
, "%s%" PRId64
".%09" PRIu64
,
196 is_negative
? "-" : "", ts_sec_abs
, ts_nsec_abs
);
202 enum bt_component_status
print_event_timestamp(struct text_component
*text
,
203 struct bt_ctf_event
*event
, bool *start_line
)
205 bool print_names
= text
->options
.print_header_field_names
;
206 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
207 struct bt_ctf_stream
*stream
= NULL
;
208 struct bt_ctf_stream_class
*stream_class
= NULL
;
209 struct bt_ctf_trace
*trace
= NULL
;
210 struct bt_ctf_clock_class
*clock_class
= NULL
;
211 FILE *out
= text
->out
;
213 stream
= bt_ctf_event_get_stream(event
);
215 ret
= BT_COMPONENT_STATUS_ERROR
;
219 stream_class
= bt_ctf_stream_get_class(stream
);
221 ret
= BT_COMPONENT_STATUS_ERROR
;
224 trace
= bt_ctf_stream_class_get_trace(stream_class
);
226 ret
= BT_COMPONENT_STATUS_ERROR
;
229 clock_class
= bt_ctf_trace_get_clock_class(trace
, 0);
231 ret
= BT_COMPONENT_STATUS_ERROR
;
235 fputs(print_names
? "timestamp = " : "[", out
);
236 if (text
->options
.print_timestamp_cycles
) {
237 print_timestamp_cycles(text
, clock_class
, event
);
239 print_timestamp_wall(text
, clock_class
, event
);
245 if (text
->options
.print_delta_field
) {
247 fputs(", delta = ", text
->out
);
249 fputs("(", text
->out
);
250 if (text
->options
.print_timestamp_cycles
) {
251 if (text
->delta_cycles
== -1ULL) {
252 fputs("+??????????\?\?) ", text
->out
); /* Not a trigraph. */
254 fprintf(text
->out
, "+%012" PRIu64
, text
->delta_cycles
);
257 if (text
->delta_real_timestamp
!= -1ULL) {
258 uint64_t delta_sec
, delta_nsec
, delta
;
260 delta
= text
->delta_real_timestamp
;
261 delta_sec
= delta
/ NSEC_PER_SEC
;
262 delta_nsec
= delta
% NSEC_PER_SEC
;
263 fprintf(text
->out
, "+%" PRIu64
".%09" PRIu64
,
264 delta_sec
, delta_nsec
);
266 fputs("+?.?????????", text
->out
);
270 fputs(") ", text
->out
);
273 *start_line
= !print_names
;
278 bt_put(stream_class
);
284 enum bt_component_status
print_event_header(struct text_component
*text
,
285 struct bt_ctf_event
*event
)
287 bool print_names
= text
->options
.print_header_field_names
;
288 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
289 struct bt_ctf_event_class
*event_class
= NULL
;
290 struct bt_ctf_stream_class
*stream_class
= NULL
;
291 struct bt_ctf_trace
*trace_class
= NULL
;
293 event_class
= bt_ctf_event_get_class(event
);
295 ret
= BT_COMPONENT_STATUS_ERROR
;
298 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
300 ret
= BT_COMPONENT_STATUS_ERROR
;
303 trace_class
= bt_ctf_stream_class_get_trace(stream_class
);
305 ret
= BT_COMPONENT_STATUS_ERROR
;
308 if (!text
->start_line
) {
309 fputs(", ", text
->out
);
311 text
->start_line
= false;
312 ret
= print_event_timestamp(text
, event
, &text
->start_line
);
313 if (ret
!= BT_COMPONENT_STATUS_OK
) {
316 if (text
->options
.print_trace_field
) {
319 name
= bt_ctf_trace_get_name(trace_class
);
321 if (!text
->start_line
) {
322 fputs(", ", text
->out
);
324 text
->start_line
= false;
326 fputs("trace = ", text
->out
);
328 fprintf(text
->out
, "%s", name
);
331 if (text
->options
.print_trace_hostname_field
) {
332 struct bt_value
*hostname_str
;
334 hostname_str
= bt_ctf_trace_get_environment_field_value_by_name(trace_class
,
339 if (!text
->start_line
) {
340 fputs(", ", text
->out
);
342 text
->start_line
= false;
344 fputs("trace:hostname = ", text
->out
);
346 if (bt_value_string_get(hostname_str
, &str
)
347 == BT_VALUE_STATUS_OK
) {
348 fprintf(text
->out
, "%s", str
);
350 bt_put(hostname_str
);
353 if (text
->options
.print_trace_domain_field
) {
354 struct bt_value
*domain_str
;
356 domain_str
= bt_ctf_trace_get_environment_field_value_by_name(trace_class
,
361 if (!text
->start_line
) {
362 fputs(", ", text
->out
);
364 text
->start_line
= false;
366 fputs("trace:domain = ", text
->out
);
368 if (bt_value_string_get(domain_str
, &str
)
369 == BT_VALUE_STATUS_OK
) {
370 fprintf(text
->out
, "%s", str
);
375 if (text
->options
.print_trace_procname_field
) {
376 struct bt_value
*procname_str
;
378 procname_str
= bt_ctf_trace_get_environment_field_value_by_name(trace_class
,
383 if (!text
->start_line
) {
384 fputs(", ", text
->out
);
386 text
->start_line
= false;
388 fputs("trace:procname = ", text
->out
);
390 if (bt_value_string_get(procname_str
, &str
)
391 == BT_VALUE_STATUS_OK
) {
392 fprintf(text
->out
, "%s", str
);
394 bt_put(procname_str
);
397 if (text
->options
.print_trace_vpid_field
) {
398 struct bt_value
*vpid_value
;
400 vpid_value
= bt_ctf_trace_get_environment_field_value_by_name(trace_class
,
405 if (!text
->start_line
) {
406 fputs(", ", text
->out
);
408 text
->start_line
= false;
410 fputs("trace:vpid = ", text
->out
);
412 if (bt_value_integer_get(vpid_value
, &value
)
413 == BT_VALUE_STATUS_OK
) {
414 fprintf(text
->out
, "(%" PRId64
")", value
);
419 if (text
->options
.print_loglevel_field
) {
420 struct bt_value
*loglevel_str
, *loglevel_value
;
422 loglevel_str
= bt_ctf_event_class_get_attribute_value_by_name(event_class
,
424 loglevel_value
= bt_ctf_event_class_get_attribute_value_by_name(event_class
,
426 if (loglevel_str
|| loglevel_value
) {
427 bool has_str
= false;
429 if (!text
->start_line
) {
430 fputs(", ", text
->out
);
432 text
->start_line
= false;
434 fputs("loglevel = ", text
->out
);
439 if (bt_value_string_get(loglevel_str
, &str
)
440 == BT_VALUE_STATUS_OK
) {
441 fprintf(text
->out
, "%s", str
);
445 if (loglevel_value
) {
448 if (bt_value_integer_get(loglevel_value
, &value
)
449 == BT_VALUE_STATUS_OK
) {
450 fprintf(text
->out
, "%s(%" PRId64
")",
451 has_str
? " " : "", value
);
454 bt_put(loglevel_str
);
455 bt_put(loglevel_value
);
458 if (text
->options
.print_emf_field
) {
459 struct bt_value
*uri_str
;
461 uri_str
= bt_ctf_event_class_get_attribute_value_by_name(event_class
,
464 if (!text
->start_line
) {
465 fputs(", ", text
->out
);
467 text
->start_line
= false;
469 fputs("model.emf.uri = ", text
->out
);
474 if (bt_value_string_get(uri_str
, &str
)
475 == BT_VALUE_STATUS_OK
) {
476 fprintf(text
->out
, "%s", str
);
482 if (!text
->start_line
) {
483 fputs(", ", text
->out
);
485 text
->start_line
= false;
487 fputs("name = ", text
->out
);
489 fputs(bt_ctf_event_class_get_name(event_class
), text
->out
);
492 bt_put(stream_class
);
498 enum bt_component_status
print_integer(struct text_component
*text
,
499 struct bt_ctf_field
*field
)
501 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
502 struct bt_ctf_field_type
*field_type
= NULL
;
503 enum bt_ctf_integer_base base
;
504 enum bt_ctf_string_encoding encoding
;
511 field_type
= bt_ctf_field_get_type(field
);
513 ret
= BT_COMPONENT_STATUS_ERROR
;
516 signedness
= bt_ctf_field_type_integer_get_signed(field_type
);
517 if (signedness
< 0) {
518 ret
= BT_COMPONENT_STATUS_ERROR
;
522 if (bt_ctf_field_unsigned_integer_get_value(field
, &v
.u
) < 0) {
523 ret
= BT_COMPONENT_STATUS_ERROR
;
527 if (bt_ctf_field_signed_integer_get_value(field
, &v
.s
) < 0) {
528 ret
= BT_COMPONENT_STATUS_ERROR
;
533 encoding
= bt_ctf_field_type_integer_get_encoding(field_type
);
535 case BT_CTF_STRING_ENCODING_UTF8
:
536 case BT_CTF_STRING_ENCODING_ASCII
:
537 g_string_append_c(text
->string
, (int) v
.u
);
539 case BT_CTF_STRING_ENCODING_NONE
:
540 case BT_CTF_STRING_ENCODING_UNKNOWN
:
543 ret
= BT_COMPONENT_STATUS_ERROR
;
547 base
= bt_ctf_field_type_integer_get_base(field_type
);
549 case BT_CTF_INTEGER_BASE_BINARY
:
553 len
= bt_ctf_field_type_integer_get_size(field_type
);
555 ret
= BT_COMPONENT_STATUS_ERROR
;
558 fprintf(text
->out
, "0b");
559 v
.u
= _bt_piecewise_lshift(v
.u
, 64 - len
);
560 for (bitnr
= 0; bitnr
< len
; bitnr
++) {
561 fprintf(text
->out
, "%u", (v
.u
& (1ULL << 63)) ? 1 : 0);
562 v
.u
= _bt_piecewise_lshift(v
.u
, 1);
566 case BT_CTF_INTEGER_BASE_OCTAL
:
571 len
= bt_ctf_field_type_integer_get_size(field_type
);
573 ret
= BT_COMPONENT_STATUS_ERROR
;
580 /* Round length to the nearest 3-bit */
581 rounded_len
= (((len
- 1) / 3) + 1) * 3;
582 v
.u
&= ((uint64_t) 1 << rounded_len
) - 1;
586 fprintf(text
->out
, "0%" PRIo64
, v
.u
);
589 case BT_CTF_INTEGER_BASE_DECIMAL
:
591 fprintf(text
->out
, "%" PRIu64
, v
.u
);
593 fprintf(text
->out
, "%" PRId64
, v
.s
);
596 case BT_CTF_INTEGER_BASE_HEXADECIMAL
:
600 len
= bt_ctf_field_type_integer_get_size(field_type
);
602 ret
= BT_COMPONENT_STATUS_ERROR
;
606 /* Round length to the nearest nibble */
607 uint8_t rounded_len
= ((len
+ 3) & ~0x3);
609 v
.u
&= ((uint64_t) 1 << rounded_len
) - 1;
612 fprintf(text
->out
, "0x%" PRIX64
, v
.u
);
616 ret
= BT_COMPONENT_STATUS_ERROR
;
625 enum bt_component_status
print_enum(struct text_component
*text
,
626 struct bt_ctf_field
*field
)
628 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
629 struct bt_ctf_field
*container_field
= NULL
;
630 struct bt_ctf_field_type
*enumeration_field_type
= NULL
;
631 struct bt_ctf_field_type
*container_field_type
= NULL
;
632 struct bt_ctf_field_type_enumeration_mapping_iterator
*iter
= NULL
;
636 enumeration_field_type
= bt_ctf_field_get_type(field
);
637 if (!enumeration_field_type
) {
638 ret
= BT_COMPONENT_STATUS_ERROR
;
641 container_field
= bt_ctf_field_enumeration_get_container(field
);
642 if (!container_field
) {
643 ret
= BT_COMPONENT_STATUS_ERROR
;
646 container_field_type
= bt_ctf_field_get_type(container_field
);
647 if (!container_field_type
) {
648 ret
= BT_COMPONENT_STATUS_ERROR
;
651 is_signed
= bt_ctf_field_type_integer_get_signed(container_field_type
);
653 ret
= BT_COMPONENT_STATUS_ERROR
;
659 if (bt_ctf_field_signed_integer_get_value(container_field
,
661 ret
= BT_COMPONENT_STATUS_ERROR
;
664 iter
= bt_ctf_field_type_enumeration_find_mappings_by_signed_value(
665 enumeration_field_type
, value
);
669 if (bt_ctf_field_unsigned_integer_get_value(container_field
,
671 ret
= BT_COMPONENT_STATUS_ERROR
;
674 iter
= bt_ctf_field_type_enumeration_find_mappings_by_unsigned_value(
675 enumeration_field_type
, value
);
678 ret
= BT_COMPONENT_STATUS_ERROR
;
681 fprintf(text
->out
, "( ");
683 const char *mapping_name
;
685 if (bt_ctf_field_type_enumeration_mapping_iterator_get_signed(
686 iter
, &mapping_name
, NULL
, NULL
) < 0) {
687 ret
= BT_COMPONENT_STATUS_ERROR
;
691 fprintf(text
->out
, ", ");
692 fprintf(text
->out
, "\"%s\"", mapping_name
);
693 if (bt_ctf_field_type_enumeration_mapping_iterator_next(iter
) < 0) {
698 fprintf(text
->out
, "<unknown>");
700 fprintf(text
->out
, " : container = ");
701 ret
= print_integer(text
, container_field
);
702 if (ret
!= BT_COMPONENT_STATUS_OK
) {
705 fprintf(text
->out
, " )");
708 bt_put(container_field_type
);
709 bt_put(container_field
);
710 bt_put(enumeration_field_type
);
715 enum bt_component_status
print_struct_field(struct text_component
*text
,
716 struct bt_ctf_field
*_struct
,
717 struct bt_ctf_field_type
*struct_type
,
718 int i
, bool print_names
)
720 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
721 const char *field_name
;
722 struct bt_ctf_field
*field
= NULL
;
723 struct bt_ctf_field_type
*field_type
= NULL
;;
725 field
= bt_ctf_field_structure_get_field_by_index(_struct
, i
);
727 ret
= BT_COMPONENT_STATUS_ERROR
;
730 if (bt_ctf_field_type_structure_get_field(struct_type
,
731 &field_name
, &field_type
, i
) < 0) {
732 ret
= BT_COMPONENT_STATUS_ERROR
;
737 fprintf(text
->out
, ", ");
739 fprintf(text
->out
, " ");
742 fprintf(text
->out
, "%s = ", rem_(field_name
));
744 ret
= print_field(text
, field
, print_names
);
752 enum bt_component_status
print_struct(struct text_component
*text
,
753 struct bt_ctf_field
*_struct
, bool print_names
)
755 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
756 struct bt_ctf_field_type
*struct_type
= NULL
;
759 struct_type
= bt_ctf_field_get_type(_struct
);
761 ret
= BT_COMPONENT_STATUS_ERROR
;
764 nr_fields
= bt_ctf_field_type_structure_get_field_count(struct_type
);
766 ret
= BT_COMPONENT_STATUS_ERROR
;
769 fprintf(text
->out
, "{");
771 for (i
= 0; i
< nr_fields
; i
++) {
772 ret
= print_struct_field(text
, _struct
, struct_type
, i
,
774 if (ret
!= BT_COMPONENT_STATUS_OK
) {
779 fprintf(text
->out
, " }");
786 enum bt_component_status
print_array_field(struct text_component
*text
,
787 struct bt_ctf_field
*array
, uint64_t i
,
788 bool is_string
, bool print_names
)
790 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
791 struct bt_ctf_field
*field
= NULL
;
795 fprintf(text
->out
, ", ");
797 fprintf(text
->out
, " ");
800 field
= bt_ctf_field_array_get_field(array
, i
);
802 ret
= BT_COMPONENT_STATUS_ERROR
;
805 ret
= print_field(text
, field
, print_names
);
812 enum bt_component_status
print_array(struct text_component
*text
,
813 struct bt_ctf_field
*array
, bool print_names
)
815 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
816 struct bt_ctf_field_type
*array_type
= NULL
, *field_type
= NULL
;
817 enum bt_ctf_type_id type_id
;
820 bool is_string
= false;
822 array_type
= bt_ctf_field_get_type(array
);
824 ret
= BT_COMPONENT_STATUS_ERROR
;
827 field_type
= bt_ctf_field_type_array_get_element_type(array_type
);
829 ret
= BT_COMPONENT_STATUS_ERROR
;
832 len
= bt_ctf_field_type_array_get_length(array_type
);
834 ret
= BT_COMPONENT_STATUS_ERROR
;
837 type_id
= bt_ctf_field_type_get_type_id(field_type
);
838 if (type_id
== BT_CTF_TYPE_ID_INTEGER
) {
839 enum bt_ctf_string_encoding encoding
;
841 encoding
= bt_ctf_field_type_integer_get_encoding(field_type
);
842 if (encoding
== BT_CTF_STRING_ENCODING_UTF8
843 || encoding
== BT_CTF_STRING_ENCODING_ASCII
) {
844 int integer_len
, integer_alignment
;
846 integer_len
= bt_ctf_field_type_integer_get_size(field_type
);
847 if (integer_len
< 0) {
848 return BT_COMPONENT_STATUS_ERROR
;
850 integer_alignment
= bt_ctf_field_type_get_alignment(field_type
);
851 if (integer_alignment
< 0) {
852 return BT_COMPONENT_STATUS_ERROR
;
854 if (integer_len
== CHAR_BIT
855 && integer_alignment
== CHAR_BIT
) {
862 g_string_assign(text
->string
, "");
864 fprintf(text
->out
, "[");
868 for (i
= 0; i
< len
; i
++) {
869 ret
= print_array_field(text
, array
, i
, is_string
, print_names
);
870 if (ret
!= BT_COMPONENT_STATUS_OK
) {
877 fprintf(text
->out
, "\"%s\"", text
->string
->str
);
879 fprintf(text
->out
, " ]");
888 enum bt_component_status
print_sequence_field(struct text_component
*text
,
889 struct bt_ctf_field
*seq
, uint64_t i
,
890 bool is_string
, bool print_names
)
892 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
893 struct bt_ctf_field
*field
= NULL
;
897 fprintf(text
->out
, ", ");
899 fprintf(text
->out
, " ");
902 field
= bt_ctf_field_sequence_get_field(seq
, i
);
904 ret
= BT_COMPONENT_STATUS_ERROR
;
907 ret
= print_field(text
, field
, print_names
);
914 enum bt_component_status
print_sequence(struct text_component
*text
,
915 struct bt_ctf_field
*seq
, bool print_names
)
917 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
918 struct bt_ctf_field_type
*seq_type
= NULL
, *field_type
= NULL
;
919 struct bt_ctf_field
*length_field
= NULL
;
920 enum bt_ctf_type_id type_id
;
923 bool is_string
= false;
925 seq_type
= bt_ctf_field_get_type(seq
);
927 ret
= BT_COMPONENT_STATUS_ERROR
;
930 length_field
= bt_ctf_field_sequence_get_length(seq
);
932 ret
= BT_COMPONENT_STATUS_ERROR
;
935 if (bt_ctf_field_unsigned_integer_get_value(length_field
, &len
) < 0) {
936 ret
= BT_COMPONENT_STATUS_ERROR
;
939 field_type
= bt_ctf_field_type_sequence_get_element_type(seq_type
);
941 ret
= BT_COMPONENT_STATUS_ERROR
;
944 type_id
= bt_ctf_field_type_get_type_id(field_type
);
945 if (type_id
== BT_CTF_TYPE_ID_INTEGER
) {
946 enum bt_ctf_string_encoding encoding
;
948 encoding
= bt_ctf_field_type_integer_get_encoding(field_type
);
949 if (encoding
== BT_CTF_STRING_ENCODING_UTF8
950 || encoding
== BT_CTF_STRING_ENCODING_ASCII
) {
951 int integer_len
, integer_alignment
;
953 integer_len
= bt_ctf_field_type_integer_get_size(field_type
);
954 if (integer_len
< 0) {
955 ret
= BT_COMPONENT_STATUS_ERROR
;
958 integer_alignment
= bt_ctf_field_type_get_alignment(field_type
);
959 if (integer_alignment
< 0) {
960 ret
= BT_COMPONENT_STATUS_ERROR
;
963 if (integer_len
== CHAR_BIT
964 && integer_alignment
== CHAR_BIT
) {
971 g_string_assign(text
->string
, "");
973 fprintf(text
->out
, "[");
977 for (i
= 0; i
< len
; i
++) {
978 ret
= print_sequence_field(text
, seq
, i
,
979 is_string
, print_names
);
980 if (ret
!= BT_COMPONENT_STATUS_OK
) {
987 fprintf(text
->out
, "\"%s\"", text
->string
->str
);
989 fprintf(text
->out
, " ]");
992 bt_put(length_field
);
999 enum bt_component_status
print_variant(struct text_component
*text
,
1000 struct bt_ctf_field
*variant
, bool print_names
)
1002 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1003 struct bt_ctf_field
*field
= NULL
;
1005 field
= bt_ctf_field_variant_get_current_field(variant
);
1007 ret
= BT_COMPONENT_STATUS_ERROR
;
1010 fprintf(text
->out
, "{ ");
1014 struct bt_ctf_field
*tag_field
= NULL
;
1015 const char *tag_choice
;
1016 struct bt_ctf_field_type_enumeration_mapping_iterator
*iter
;
1018 tag_field
= bt_ctf_field_variant_get_tag(variant
);
1020 ret
= BT_COMPONENT_STATUS_ERROR
;
1024 iter
= bt_ctf_field_enumeration_get_mappings(tag_field
);
1027 ret
= BT_COMPONENT_STATUS_ERROR
;
1032 bt_ctf_field_type_enumeration_mapping_iterator_get_signed(
1033 iter
, &tag_choice
, NULL
, NULL
);
1037 ret
= BT_COMPONENT_STATUS_ERROR
;
1040 fprintf(text
->out
, "%s = ", rem_(tag_choice
));
1044 ret
= print_field(text
, field
, print_names
);
1045 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1049 fprintf(text
->out
, " }");
1056 enum bt_component_status
print_field(struct text_component
*text
,
1057 struct bt_ctf_field
*field
, bool print_names
)
1059 enum bt_ctf_type_id type_id
;
1061 type_id
= bt_ctf_field_get_type_id(field
);
1063 case CTF_TYPE_INTEGER
:
1064 return print_integer(text
, field
);
1065 case CTF_TYPE_FLOAT
:
1069 if (bt_ctf_field_floating_point_get_value(field
, &v
)) {
1070 return BT_COMPONENT_STATUS_ERROR
;
1072 fprintf(text
->out
, "%g", v
);
1073 return BT_COMPONENT_STATUS_OK
;
1076 return print_enum(text
, field
);
1077 case CTF_TYPE_STRING
:
1078 fprintf(text
->out
, "\"%s\"", bt_ctf_field_string_get_value(field
));
1079 return BT_COMPONENT_STATUS_OK
;
1080 case CTF_TYPE_STRUCT
:
1081 return print_struct(text
, field
, print_names
);
1082 case CTF_TYPE_UNTAGGED_VARIANT
:
1083 case CTF_TYPE_VARIANT
:
1084 return print_variant(text
, field
, print_names
);
1085 case CTF_TYPE_ARRAY
:
1086 return print_array(text
, field
, print_names
);
1087 case CTF_TYPE_SEQUENCE
:
1088 return print_sequence(text
, field
, print_names
);
1090 fprintf(text
->err
, "[error] Unknown type id: %d\n", (int) type_id
);
1091 return BT_COMPONENT_STATUS_ERROR
;
1096 enum bt_component_status
print_stream_packet_context(struct text_component
*text
,
1097 struct bt_ctf_event
*event
)
1099 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1100 struct bt_ctf_packet
*packet
= NULL
;
1101 struct bt_ctf_field
*main_field
= NULL
;
1103 packet
= bt_ctf_event_get_packet(event
);
1105 ret
= BT_COMPONENT_STATUS_ERROR
;
1108 main_field
= bt_ctf_packet_get_context(packet
);
1112 if (!text
->start_line
) {
1113 fputs(", ", text
->out
);
1115 text
->start_line
= false;
1116 if (text
->options
.print_scope_field_names
) {
1117 fputs("stream.packet.context = ", text
->out
);
1119 ret
= print_field(text
, main_field
,
1120 text
->options
.print_context_field_names
);
1128 enum bt_component_status
print_event_header_raw(struct text_component
*text
,
1129 struct bt_ctf_event
*event
)
1131 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1132 struct bt_ctf_field
*main_field
= NULL
;
1134 main_field
= bt_ctf_event_get_header(event
);
1138 if (!text
->start_line
) {
1139 fputs(", ", text
->out
);
1141 text
->start_line
= false;
1142 if (text
->options
.print_scope_field_names
) {
1143 fputs("stream.event.header = ", text
->out
);
1145 ret
= print_field(text
, main_field
,
1146 text
->options
.print_header_field_names
);
1153 enum bt_component_status
print_stream_event_context(struct text_component
*text
,
1154 struct bt_ctf_event
*event
)
1156 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1157 struct bt_ctf_field
*main_field
= NULL
;
1159 main_field
= bt_ctf_event_get_stream_event_context(event
);
1163 if (!text
->start_line
) {
1164 fputs(", ", text
->out
);
1166 text
->start_line
= false;
1167 if (text
->options
.print_scope_field_names
) {
1168 fputs("stream.event.context = ", text
->out
);
1170 ret
= print_field(text
, main_field
,
1171 text
->options
.print_context_field_names
);
1178 enum bt_component_status
print_event_context(struct text_component
*text
,
1179 struct bt_ctf_event
*event
)
1181 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1182 struct bt_ctf_field
*main_field
= NULL
;
1184 main_field
= bt_ctf_event_get_event_context(event
);
1188 if (!text
->start_line
) {
1189 fputs(", ", text
->out
);
1191 text
->start_line
= false;
1192 if (text
->options
.print_scope_field_names
) {
1193 fputs("event.context = ", text
->out
);
1195 ret
= print_field(text
, main_field
,
1196 text
->options
.print_context_field_names
);
1203 enum bt_component_status
print_event_payload(struct text_component
*text
,
1204 struct bt_ctf_event
*event
)
1206 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1207 struct bt_ctf_field
*main_field
= NULL
;
1209 main_field
= bt_ctf_event_get_payload_field(event
);
1213 if (!text
->start_line
) {
1214 fputs(", ", text
->out
);
1216 text
->start_line
= false;
1217 if (text
->options
.print_scope_field_names
) {
1218 fputs("event.fields = ", text
->out
);
1220 ret
= print_field(text
, main_field
,
1221 text
->options
.print_payload_field_names
);
1228 enum bt_component_status
text_print_event(struct text_component
*text
,
1229 struct bt_ctf_event
*event
)
1231 enum bt_component_status ret
;
1233 text
->start_line
= true;
1234 ret
= print_event_header(text
, event
);
1235 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1239 ret
= print_stream_packet_context(text
, event
);
1240 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1244 ret
= print_event_header_raw(text
, event
);
1245 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1249 ret
= print_stream_event_context(text
, event
);
1250 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1254 ret
= print_event_context(text
, event
);
1255 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1259 ret
= print_event_payload(text
, event
);
1260 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1264 fputc('\n', text
->out
);