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/graph/notification-event.h>
40 #include <babeltrace/graph/clock-class-priority-map.h>
41 #include <babeltrace/bitfield-internal.h>
42 #include <babeltrace/common-internal.h>
47 #define NSEC_PER_SEC 1000000000LL
49 #define COLOR_NAME BT_COMMON_COLOR_BOLD
50 #define COLOR_FIELD_NAME BT_COMMON_COLOR_FG_CYAN
51 #define COLOR_RST BT_COMMON_COLOR_RESET
52 #define COLOR_STRING_VALUE BT_COMMON_COLOR_BOLD
53 #define COLOR_NUMBER_VALUE BT_COMMON_COLOR_BOLD
54 #define COLOR_ENUM_MAPPING_NAME BT_COMMON_COLOR_BOLD
55 #define COLOR_UNKNOWN BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_RED
56 #define COLOR_EVENT_NAME BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_MAGENTA
57 #define COLOR_TIMESTAMP BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_YELLOW
60 const char *rem_(const char *str
)
69 int64_t real_timestamp
; /* Relative to UNIX epoch. */
70 uint64_t clock_value
; /* In cycles. */
74 enum bt_component_status
print_field(struct pretty_component
*pretty
,
75 struct bt_ctf_field
*field
, bool print_names
,
76 GQuark
*filters_fields
, int filter_array_len
);
79 void print_name_equal(struct pretty_component
*pretty
, const char *name
)
81 if (pretty
->use_colors
) {
82 fprintf(pretty
->out
, "%s%s%s = ", COLOR_NAME
, name
, COLOR_RST
);
84 fprintf(pretty
->out
, "%s = ", name
);
89 void print_field_name_equal(struct pretty_component
*pretty
, const char *name
)
91 if (pretty
->use_colors
) {
92 fprintf(pretty
->out
, "%s%s%s = ", COLOR_FIELD_NAME
, name
,
95 fprintf(pretty
->out
, "%s = ", name
);
100 void print_timestamp_cycles(struct pretty_component
*pretty
,
101 struct bt_ctf_clock_class
*clock_class
,
102 struct bt_ctf_event
*event
)
105 struct bt_ctf_clock_value
*clock_value
;
108 clock_value
= bt_ctf_event_get_clock_value(event
, clock_class
);
110 fputs("????????????????????", pretty
->out
);
114 ret
= bt_ctf_clock_value_get_value(clock_value
, &cycles
);
117 fprintf(pretty
->out
, "Error");
120 fprintf(pretty
->out
, "%020" PRIu64
, cycles
);
122 if (pretty
->last_cycles_timestamp
!= -1ULL) {
123 pretty
->delta_cycles
= cycles
- pretty
->last_cycles_timestamp
;
125 pretty
->last_cycles_timestamp
= cycles
;
129 void print_timestamp_wall(struct pretty_component
*pretty
,
130 struct bt_ctf_clock_class
*clock_class
,
131 struct bt_ctf_event
*event
)
134 struct bt_ctf_clock_value
*clock_value
;
135 int64_t ts_nsec
= 0; /* add configurable offset */
136 int64_t ts_sec
= 0; /* add configurable offset */
137 uint64_t ts_sec_abs
, ts_nsec_abs
;
140 clock_value
= bt_ctf_event_get_clock_value(event
, clock_class
);
142 fputs("??:??:??.?????????", pretty
->out
);
146 ret
= bt_ctf_clock_value_get_value_ns_from_epoch(clock_value
, &ts_nsec
);
149 fprintf(pretty
->out
, "Error");
153 if (pretty
->last_real_timestamp
!= -1ULL) {
154 pretty
->delta_real_timestamp
= ts_nsec
- pretty
->last_real_timestamp
;
156 pretty
->last_real_timestamp
= ts_nsec
;
158 ts_sec
+= ts_nsec
/ NSEC_PER_SEC
;
159 ts_nsec
= ts_nsec
% NSEC_PER_SEC
;
160 if (ts_sec
>= 0 && ts_nsec
>= 0) {
163 ts_nsec_abs
= ts_nsec
;
164 } else if (ts_sec
> 0 && ts_nsec
< 0) {
166 ts_sec_abs
= ts_sec
- 1;
167 ts_nsec_abs
= NSEC_PER_SEC
+ ts_nsec
;
168 } else if (ts_sec
== 0 && ts_nsec
< 0) {
171 ts_nsec_abs
= -ts_nsec
;
172 } else if (ts_sec
< 0 && ts_nsec
> 0) {
174 ts_sec_abs
= -(ts_sec
+ 1);
175 ts_nsec_abs
= NSEC_PER_SEC
- ts_nsec
;
176 } else if (ts_sec
< 0 && ts_nsec
== 0) {
178 ts_sec_abs
= -ts_sec
;
179 ts_nsec_abs
= ts_nsec
;
180 } else { /* (ts_sec < 0 && ts_nsec < 0) */
182 ts_sec_abs
= -ts_sec
;
183 ts_nsec_abs
= -ts_nsec
;
186 if (!pretty
->options
.clock_seconds
) {
188 time_t time_s
= (time_t) ts_sec_abs
;
191 fprintf(stderr
, "[warning] Fallback to [sec.ns] to print negative time value. Use --clock-seconds.\n");
195 if (!pretty
->options
.clock_gmt
) {
198 res
= localtime_r(&time_s
, &tm
);
200 fprintf(stderr
, "[warning] Unable to get localtime.\n");
206 res
= gmtime_r(&time_s
, &tm
);
208 fprintf(stderr
, "[warning] Unable to get gmtime.\n");
212 if (pretty
->options
.clock_date
) {
216 /* Print date and time */
217 res
= strftime(timestr
, sizeof(timestr
),
220 fprintf(stderr
, "[warning] Unable to print ascii time.\n");
223 fprintf(pretty
->out
, "%s", timestr
);
225 /* Print time in HH:MM:SS.ns */
226 fprintf(pretty
->out
, "%02d:%02d:%02d.%09" PRIu64
,
227 tm
.tm_hour
, tm
.tm_min
, tm
.tm_sec
, ts_nsec_abs
);
231 fprintf(pretty
->out
, "%s%" PRId64
".%09" PRIu64
,
232 is_negative
? "-" : "", ts_sec_abs
, ts_nsec_abs
);
238 enum bt_component_status
print_event_timestamp(struct pretty_component
*pretty
,
239 struct bt_ctf_event
*event
,
240 struct bt_clock_class_priority_map
*cc_prio_map
,
243 bool print_names
= pretty
->options
.print_header_field_names
;
244 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
245 struct bt_ctf_stream
*stream
= NULL
;
246 struct bt_ctf_stream_class
*stream_class
= NULL
;
247 struct bt_ctf_trace
*trace
= NULL
;
248 struct bt_ctf_clock_class
*clock_class
= NULL
;
249 FILE *out
= pretty
->out
;
251 stream
= bt_ctf_event_get_stream(event
);
253 ret
= BT_COMPONENT_STATUS_ERROR
;
257 stream_class
= bt_ctf_stream_get_class(stream
);
259 ret
= BT_COMPONENT_STATUS_ERROR
;
262 trace
= bt_ctf_stream_class_get_trace(stream_class
);
264 ret
= BT_COMPONENT_STATUS_ERROR
;
268 if (bt_clock_class_priority_map_get_clock_class_count(cc_prio_map
) == 0) {
269 /* No clock class: skip the timestamp without an error */
274 bt_clock_class_priority_map_get_highest_priority_clock_class(
277 ret
= BT_COMPONENT_STATUS_ERROR
;
282 print_name_equal(pretty
, "timestamp");
286 if (pretty
->use_colors
) {
287 fputs(COLOR_TIMESTAMP
, pretty
->out
);
289 if (pretty
->options
.print_timestamp_cycles
) {
290 print_timestamp_cycles(pretty
, clock_class
, event
);
292 print_timestamp_wall(pretty
, clock_class
, event
);
294 if (pretty
->use_colors
) {
295 fputs(COLOR_RST
, pretty
->out
);
301 if (pretty
->options
.print_delta_field
) {
303 fputs(", ", pretty
->out
);
304 print_name_equal(pretty
, "delta");
306 fputs("(", pretty
->out
);
308 if (pretty
->options
.print_timestamp_cycles
) {
309 if (pretty
->delta_cycles
== -1ULL) {
310 fputs("+??????????\?\?) ", pretty
->out
); /* Not a trigraph. */
312 fprintf(pretty
->out
, "+%012" PRIu64
, pretty
->delta_cycles
);
315 if (pretty
->delta_real_timestamp
!= -1ULL) {
316 uint64_t delta_sec
, delta_nsec
, delta
;
318 delta
= pretty
->delta_real_timestamp
;
319 delta_sec
= delta
/ NSEC_PER_SEC
;
320 delta_nsec
= delta
% NSEC_PER_SEC
;
321 fprintf(pretty
->out
, "+%" PRIu64
".%09" PRIu64
,
322 delta_sec
, delta_nsec
);
324 fputs("+?.?????????", pretty
->out
);
328 fputs(") ", pretty
->out
);
331 *start_line
= !print_names
;
336 bt_put(stream_class
);
342 enum bt_component_status
print_event_header(struct pretty_component
*pretty
,
343 struct bt_ctf_event
*event
,
344 struct bt_clock_class_priority_map
*cc_prio_map
)
346 bool print_names
= pretty
->options
.print_header_field_names
;
347 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
348 struct bt_ctf_event_class
*event_class
= NULL
;
349 struct bt_ctf_stream_class
*stream_class
= NULL
;
350 struct bt_ctf_trace
*trace_class
= NULL
;
353 event_class
= bt_ctf_event_get_class(event
);
355 ret
= BT_COMPONENT_STATUS_ERROR
;
358 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
360 ret
= BT_COMPONENT_STATUS_ERROR
;
363 trace_class
= bt_ctf_stream_class_get_trace(stream_class
);
365 ret
= BT_COMPONENT_STATUS_ERROR
;
368 ret
= print_event_timestamp(pretty
, event
, cc_prio_map
,
369 &pretty
->start_line
);
370 if (ret
!= BT_COMPONENT_STATUS_OK
) {
373 if (pretty
->options
.print_trace_field
) {
376 name
= bt_ctf_trace_get_name(trace_class
);
378 if (!pretty
->start_line
) {
379 fputs(", ", pretty
->out
);
382 print_name_equal(pretty
, "trace");
384 fprintf(pretty
->out
, "%s", name
);
386 fprintf(pretty
->out
, " ");
390 if (pretty
->options
.print_trace_hostname_field
) {
391 struct bt_value
*hostname_str
;
393 hostname_str
= bt_ctf_trace_get_environment_field_value_by_name(trace_class
,
398 if (!pretty
->start_line
) {
399 fputs(", ", pretty
->out
);
402 print_name_equal(pretty
, "trace:hostname");
404 if (bt_value_string_get(hostname_str
, &str
)
405 == BT_VALUE_STATUS_OK
) {
406 fprintf(pretty
->out
, "%s", str
);
408 bt_put(hostname_str
);
412 if (pretty
->options
.print_trace_domain_field
) {
413 struct bt_value
*domain_str
;
415 domain_str
= bt_ctf_trace_get_environment_field_value_by_name(trace_class
,
420 if (!pretty
->start_line
) {
421 fputs(", ", pretty
->out
);
424 print_name_equal(pretty
, "trace:domain");
425 } else if (dom_print
) {
426 fputs(":", pretty
->out
);
428 if (bt_value_string_get(domain_str
, &str
)
429 == BT_VALUE_STATUS_OK
) {
430 fprintf(pretty
->out
, "%s", str
);
436 if (pretty
->options
.print_trace_procname_field
) {
437 struct bt_value
*procname_str
;
439 procname_str
= bt_ctf_trace_get_environment_field_value_by_name(trace_class
,
444 if (!pretty
->start_line
) {
445 fputs(", ", pretty
->out
);
448 print_name_equal(pretty
, "trace:procname");
449 } else if (dom_print
) {
450 fputs(":", pretty
->out
);
452 if (bt_value_string_get(procname_str
, &str
)
453 == BT_VALUE_STATUS_OK
) {
454 fprintf(pretty
->out
, "%s", str
);
456 bt_put(procname_str
);
460 if (pretty
->options
.print_trace_vpid_field
) {
461 struct bt_value
*vpid_value
;
463 vpid_value
= bt_ctf_trace_get_environment_field_value_by_name(trace_class
,
468 if (!pretty
->start_line
) {
469 fputs(", ", pretty
->out
);
472 print_name_equal(pretty
, "trace:vpid");
473 } else if (dom_print
) {
474 fputs(":", pretty
->out
);
476 if (bt_value_integer_get(vpid_value
, &value
)
477 == BT_VALUE_STATUS_OK
) {
478 fprintf(pretty
->out
, "(%" PRId64
")", value
);
484 if (pretty
->options
.print_loglevel_field
) {
485 struct bt_value
*loglevel_str
, *loglevel_value
;
487 loglevel_str
= bt_ctf_event_class_get_attribute_value_by_name(event_class
,
489 loglevel_value
= bt_ctf_event_class_get_attribute_value_by_name(event_class
,
491 if (loglevel_str
|| loglevel_value
) {
492 bool has_str
= false;
494 if (!pretty
->start_line
) {
495 fputs(", ", pretty
->out
);
498 print_name_equal(pretty
, "loglevel");
499 } else if (dom_print
) {
500 fputs(":", pretty
->out
);
505 if (bt_value_string_get(loglevel_str
, &str
)
506 == BT_VALUE_STATUS_OK
) {
507 fprintf(pretty
->out
, "%s", str
);
511 if (loglevel_value
) {
514 if (bt_value_integer_get(loglevel_value
, &value
)
515 == BT_VALUE_STATUS_OK
) {
516 fprintf(pretty
->out
, "%s(%" PRId64
")",
517 has_str
? " " : "", value
);
520 bt_put(loglevel_str
);
521 bt_put(loglevel_value
);
525 if (pretty
->options
.print_emf_field
) {
526 struct bt_value
*uri_str
;
528 uri_str
= bt_ctf_event_class_get_attribute_value_by_name(event_class
,
531 if (!pretty
->start_line
) {
532 fputs(", ", pretty
->out
);
535 print_name_equal(pretty
, "model.emf.uri");
536 } else if (dom_print
) {
537 fputs(":", pretty
->out
);
542 if (bt_value_string_get(uri_str
, &str
)
543 == BT_VALUE_STATUS_OK
) {
544 fprintf(pretty
->out
, "%s", str
);
551 if (dom_print
&& !print_names
) {
552 fputs(" ", pretty
->out
);
554 if (!pretty
->start_line
) {
555 fputs(", ", pretty
->out
);
557 pretty
->start_line
= true;
559 print_name_equal(pretty
, "name");
561 if (pretty
->use_colors
) {
562 fputs(COLOR_EVENT_NAME
, pretty
->out
);
564 fputs(bt_ctf_event_class_get_name(event_class
), pretty
->out
);
565 if (pretty
->use_colors
) {
566 fputs(COLOR_RST
, pretty
->out
);
569 fputs(": ", pretty
->out
);
571 fputs(", ", pretty
->out
);
575 bt_put(stream_class
);
581 enum bt_component_status
print_integer(struct pretty_component
*pretty
,
582 struct bt_ctf_field
*field
)
584 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
585 struct bt_ctf_field_type
*field_type
= NULL
;
586 enum bt_ctf_integer_base base
;
587 enum bt_ctf_string_encoding encoding
;
593 bool rst_color
= false;
595 field_type
= bt_ctf_field_get_type(field
);
597 ret
= BT_COMPONENT_STATUS_ERROR
;
600 signedness
= bt_ctf_field_type_integer_get_signed(field_type
);
601 if (signedness
< 0) {
602 ret
= BT_COMPONENT_STATUS_ERROR
;
606 if (bt_ctf_field_unsigned_integer_get_value(field
, &v
.u
) < 0) {
607 ret
= BT_COMPONENT_STATUS_ERROR
;
611 if (bt_ctf_field_signed_integer_get_value(field
, &v
.s
) < 0) {
612 ret
= BT_COMPONENT_STATUS_ERROR
;
617 encoding
= bt_ctf_field_type_integer_get_encoding(field_type
);
619 case BT_CTF_STRING_ENCODING_UTF8
:
620 case BT_CTF_STRING_ENCODING_ASCII
:
621 g_string_append_c(pretty
->string
, (int) v
.u
);
623 case BT_CTF_STRING_ENCODING_NONE
:
624 case BT_CTF_STRING_ENCODING_UNKNOWN
:
627 ret
= BT_COMPONENT_STATUS_ERROR
;
631 if (pretty
->use_colors
) {
632 fputs(COLOR_NUMBER_VALUE
, pretty
->out
);
636 base
= bt_ctf_field_type_integer_get_base(field_type
);
638 case BT_CTF_INTEGER_BASE_BINARY
:
642 len
= bt_ctf_field_type_integer_get_size(field_type
);
644 ret
= BT_COMPONENT_STATUS_ERROR
;
647 fprintf(pretty
->out
, "0b");
648 v
.u
= _bt_piecewise_lshift(v
.u
, 64 - len
);
649 for (bitnr
= 0; bitnr
< len
; bitnr
++) {
650 fprintf(pretty
->out
, "%u", (v
.u
& (1ULL << 63)) ? 1 : 0);
651 v
.u
= _bt_piecewise_lshift(v
.u
, 1);
655 case BT_CTF_INTEGER_BASE_OCTAL
:
660 len
= bt_ctf_field_type_integer_get_size(field_type
);
662 ret
= BT_COMPONENT_STATUS_ERROR
;
669 /* Round length to the nearest 3-bit */
670 rounded_len
= (((len
- 1) / 3) + 1) * 3;
671 v
.u
&= ((uint64_t) 1 << rounded_len
) - 1;
675 fprintf(pretty
->out
, "0%" PRIo64
, v
.u
);
678 case BT_CTF_INTEGER_BASE_DECIMAL
:
680 fprintf(pretty
->out
, "%" PRIu64
, v
.u
);
682 fprintf(pretty
->out
, "%" PRId64
, v
.s
);
685 case BT_CTF_INTEGER_BASE_HEXADECIMAL
:
689 len
= bt_ctf_field_type_integer_get_size(field_type
);
691 ret
= BT_COMPONENT_STATUS_ERROR
;
695 /* Round length to the nearest nibble */
696 uint8_t rounded_len
= ((len
+ 3) & ~0x3);
698 v
.u
&= ((uint64_t) 1 << rounded_len
) - 1;
701 fprintf(pretty
->out
, "0x%" PRIX64
, v
.u
);
705 ret
= BT_COMPONENT_STATUS_ERROR
;
710 fputs(COLOR_RST
, pretty
->out
);
717 void print_escape_string(struct pretty_component
*pretty
, const char *str
)
721 fputc('"', pretty
->out
);
722 for (i
= 0; i
< strlen(str
); i
++) {
723 /* Escape sequences not recognized by iscntrl(). */
726 fputs("\\\\", pretty
->out
);
729 fputs("\\\'", pretty
->out
);
732 fputs("\\\"", pretty
->out
);
735 fputs("\\\?", pretty
->out
);
739 /* Standard characters. */
740 if (!iscntrl(str
[i
])) {
741 fputc(str
[i
], pretty
->out
);
747 fputs("\\0", pretty
->out
);
750 fputs("\\a", pretty
->out
);
753 fputs("\\b", pretty
->out
);
756 fputs("\\e", pretty
->out
);
759 fputs("\\f", pretty
->out
);
762 fputs("\\n", pretty
->out
);
765 fputs("\\r", pretty
->out
);
768 fputs("\\t", pretty
->out
);
771 fputs("\\v", pretty
->out
);
774 /* Unhandled control-sequence, print as hex. */
775 fprintf(pretty
->out
, "\\x%02x", str
[i
]);
779 fputc('"', pretty
->out
);
783 enum bt_component_status
print_enum(struct pretty_component
*pretty
,
784 struct bt_ctf_field
*field
)
786 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
787 struct bt_ctf_field
*container_field
= NULL
;
788 struct bt_ctf_field_type
*enumeration_field_type
= NULL
;
789 struct bt_ctf_field_type
*container_field_type
= NULL
;
790 struct bt_ctf_field_type_enumeration_mapping_iterator
*iter
= NULL
;
794 enumeration_field_type
= bt_ctf_field_get_type(field
);
795 if (!enumeration_field_type
) {
796 ret
= BT_COMPONENT_STATUS_ERROR
;
799 container_field
= bt_ctf_field_enumeration_get_container(field
);
800 if (!container_field
) {
801 ret
= BT_COMPONENT_STATUS_ERROR
;
804 container_field_type
= bt_ctf_field_get_type(container_field
);
805 if (!container_field_type
) {
806 ret
= BT_COMPONENT_STATUS_ERROR
;
809 is_signed
= bt_ctf_field_type_integer_get_signed(container_field_type
);
811 ret
= BT_COMPONENT_STATUS_ERROR
;
817 if (bt_ctf_field_signed_integer_get_value(container_field
,
819 ret
= BT_COMPONENT_STATUS_ERROR
;
822 iter
= bt_ctf_field_type_enumeration_find_mappings_by_signed_value(
823 enumeration_field_type
, value
);
827 if (bt_ctf_field_unsigned_integer_get_value(container_field
,
829 ret
= BT_COMPONENT_STATUS_ERROR
;
832 iter
= bt_ctf_field_type_enumeration_find_mappings_by_unsigned_value(
833 enumeration_field_type
, value
);
836 ret
= BT_COMPONENT_STATUS_ERROR
;
839 fprintf(pretty
->out
, "( ");
841 const char *mapping_name
;
843 if (bt_ctf_field_type_enumeration_mapping_iterator_get_signed(
844 iter
, &mapping_name
, NULL
, NULL
) < 0) {
845 ret
= BT_COMPONENT_STATUS_ERROR
;
849 fprintf(pretty
->out
, ", ");
850 if (pretty
->use_colors
) {
851 fputs(COLOR_ENUM_MAPPING_NAME
, pretty
->out
);
853 print_escape_string(pretty
, mapping_name
);
854 if (pretty
->use_colors
) {
855 fputs(COLOR_RST
, pretty
->out
);
857 if (bt_ctf_field_type_enumeration_mapping_iterator_next(iter
) < 0) {
862 if (pretty
->use_colors
) {
863 fputs(COLOR_UNKNOWN
, pretty
->out
);
865 fprintf(pretty
->out
, "<unknown>");
866 if (pretty
->use_colors
) {
867 fputs(COLOR_RST
, pretty
->out
);
870 fprintf(pretty
->out
, " : container = ");
871 ret
= print_integer(pretty
, container_field
);
872 if (ret
!= BT_COMPONENT_STATUS_OK
) {
875 fprintf(pretty
->out
, " )");
878 bt_put(container_field_type
);
879 bt_put(container_field
);
880 bt_put(enumeration_field_type
);
885 int filter_field_name(struct pretty_component
*pretty
, const char *field_name
,
886 GQuark
*filter_fields
, int filter_array_len
)
889 GQuark field_quark
= g_quark_try_string(field_name
);
891 if (!field_quark
|| pretty
->options
.verbose
) {
895 for (i
= 0; i
< filter_array_len
; i
++) {
896 if (field_quark
== filter_fields
[i
]) {
904 enum bt_component_status
print_struct_field(struct pretty_component
*pretty
,
905 struct bt_ctf_field
*_struct
,
906 struct bt_ctf_field_type
*struct_type
,
907 int i
, bool print_names
, int *nr_printed_fields
,
908 GQuark
*filter_fields
, int filter_array_len
)
910 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
911 const char *field_name
;
912 struct bt_ctf_field
*field
= NULL
;
913 struct bt_ctf_field_type
*field_type
= NULL
;;
915 field
= bt_ctf_field_structure_get_field_by_index(_struct
, i
);
917 ret
= BT_COMPONENT_STATUS_ERROR
;
920 if (bt_ctf_field_type_structure_get_field(struct_type
,
921 &field_name
, &field_type
, i
) < 0) {
922 ret
= BT_COMPONENT_STATUS_ERROR
;
926 if (filter_fields
&& !filter_field_name(pretty
, field_name
,
927 filter_fields
, filter_array_len
)) {
928 ret
= BT_COMPONENT_STATUS_OK
;
932 if (*nr_printed_fields
> 0) {
933 fprintf(pretty
->out
, ", ");
935 fprintf(pretty
->out
, " ");
938 print_field_name_equal(pretty
, rem_(field_name
));
940 ret
= print_field(pretty
, field
, print_names
, NULL
, 0);
941 *nr_printed_fields
+= 1;
949 enum bt_component_status
print_struct(struct pretty_component
*pretty
,
950 struct bt_ctf_field
*_struct
, bool print_names
,
951 GQuark
*filter_fields
, int filter_array_len
)
953 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
954 struct bt_ctf_field_type
*struct_type
= NULL
;
955 int nr_fields
, i
, nr_printed_fields
;
957 struct_type
= bt_ctf_field_get_type(_struct
);
959 ret
= BT_COMPONENT_STATUS_ERROR
;
962 nr_fields
= bt_ctf_field_type_structure_get_field_count(struct_type
);
964 ret
= BT_COMPONENT_STATUS_ERROR
;
967 fprintf(pretty
->out
, "{");
969 nr_printed_fields
= 0;
970 for (i
= 0; i
< nr_fields
; i
++) {
971 ret
= print_struct_field(pretty
, _struct
, struct_type
, i
,
972 print_names
, &nr_printed_fields
, filter_fields
,
974 if (ret
!= BT_COMPONENT_STATUS_OK
) {
979 fprintf(pretty
->out
, " }");
986 enum bt_component_status
print_array_field(struct pretty_component
*pretty
,
987 struct bt_ctf_field
*array
, uint64_t i
,
988 bool is_string
, bool print_names
)
990 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
991 struct bt_ctf_field
*field
= NULL
;
995 fprintf(pretty
->out
, ", ");
997 fprintf(pretty
->out
, " ");
1000 fprintf(pretty
->out
, "[%" PRIu64
"] = ", i
);
1003 field
= bt_ctf_field_array_get_field(array
, i
);
1005 ret
= BT_COMPONENT_STATUS_ERROR
;
1008 ret
= print_field(pretty
, field
, print_names
, NULL
, 0);
1015 enum bt_component_status
print_array(struct pretty_component
*pretty
,
1016 struct bt_ctf_field
*array
, bool print_names
)
1018 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1019 struct bt_ctf_field_type
*array_type
= NULL
, *field_type
= NULL
;
1020 enum bt_ctf_field_type_id type_id
;
1023 bool is_string
= false;
1025 array_type
= bt_ctf_field_get_type(array
);
1027 ret
= BT_COMPONENT_STATUS_ERROR
;
1030 field_type
= bt_ctf_field_type_array_get_element_type(array_type
);
1032 ret
= BT_COMPONENT_STATUS_ERROR
;
1035 len
= bt_ctf_field_type_array_get_length(array_type
);
1037 ret
= BT_COMPONENT_STATUS_ERROR
;
1040 type_id
= bt_ctf_field_type_get_type_id(field_type
);
1041 if (type_id
== BT_CTF_FIELD_TYPE_ID_INTEGER
) {
1042 enum bt_ctf_string_encoding encoding
;
1044 encoding
= bt_ctf_field_type_integer_get_encoding(field_type
);
1045 if (encoding
== BT_CTF_STRING_ENCODING_UTF8
1046 || encoding
== BT_CTF_STRING_ENCODING_ASCII
) {
1047 int integer_len
, integer_alignment
;
1049 integer_len
= bt_ctf_field_type_integer_get_size(field_type
);
1050 if (integer_len
< 0) {
1051 return BT_COMPONENT_STATUS_ERROR
;
1053 integer_alignment
= bt_ctf_field_type_get_alignment(field_type
);
1054 if (integer_alignment
< 0) {
1055 return BT_COMPONENT_STATUS_ERROR
;
1057 if (integer_len
== CHAR_BIT
1058 && integer_alignment
== CHAR_BIT
) {
1065 g_string_assign(pretty
->string
, "");
1067 fprintf(pretty
->out
, "[");
1071 for (i
= 0; i
< len
; i
++) {
1072 ret
= print_array_field(pretty
, array
, i
, is_string
, print_names
);
1073 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1080 if (pretty
->use_colors
) {
1081 fputs(COLOR_STRING_VALUE
, pretty
->out
);
1083 print_escape_string(pretty
, pretty
->string
->str
);
1084 if (pretty
->use_colors
) {
1085 fputs(COLOR_RST
, pretty
->out
);
1088 fprintf(pretty
->out
, " ]");
1097 enum bt_component_status
print_sequence_field(struct pretty_component
*pretty
,
1098 struct bt_ctf_field
*seq
, uint64_t i
,
1099 bool is_string
, bool print_names
)
1101 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1102 struct bt_ctf_field
*field
= NULL
;
1106 fprintf(pretty
->out
, ", ");
1108 fprintf(pretty
->out
, " ");
1111 fprintf(pretty
->out
, "[%" PRIu64
"] = ", i
);
1114 field
= bt_ctf_field_sequence_get_field(seq
, i
);
1116 ret
= BT_COMPONENT_STATUS_ERROR
;
1119 ret
= print_field(pretty
, field
, print_names
, NULL
, 0);
1126 enum bt_component_status
print_sequence(struct pretty_component
*pretty
,
1127 struct bt_ctf_field
*seq
, bool print_names
)
1129 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1130 struct bt_ctf_field_type
*seq_type
= NULL
, *field_type
= NULL
;
1131 struct bt_ctf_field
*length_field
= NULL
;
1132 enum bt_ctf_field_type_id type_id
;
1135 bool is_string
= false;
1137 seq_type
= bt_ctf_field_get_type(seq
);
1139 ret
= BT_COMPONENT_STATUS_ERROR
;
1142 length_field
= bt_ctf_field_sequence_get_length(seq
);
1143 if (!length_field
) {
1144 ret
= BT_COMPONENT_STATUS_ERROR
;
1147 if (bt_ctf_field_unsigned_integer_get_value(length_field
, &len
) < 0) {
1148 ret
= BT_COMPONENT_STATUS_ERROR
;
1151 field_type
= bt_ctf_field_type_sequence_get_element_type(seq_type
);
1153 ret
= BT_COMPONENT_STATUS_ERROR
;
1156 type_id
= bt_ctf_field_type_get_type_id(field_type
);
1157 if (type_id
== BT_CTF_FIELD_TYPE_ID_INTEGER
) {
1158 enum bt_ctf_string_encoding encoding
;
1160 encoding
= bt_ctf_field_type_integer_get_encoding(field_type
);
1161 if (encoding
== BT_CTF_STRING_ENCODING_UTF8
1162 || encoding
== BT_CTF_STRING_ENCODING_ASCII
) {
1163 int integer_len
, integer_alignment
;
1165 integer_len
= bt_ctf_field_type_integer_get_size(field_type
);
1166 if (integer_len
< 0) {
1167 ret
= BT_COMPONENT_STATUS_ERROR
;
1170 integer_alignment
= bt_ctf_field_type_get_alignment(field_type
);
1171 if (integer_alignment
< 0) {
1172 ret
= BT_COMPONENT_STATUS_ERROR
;
1175 if (integer_len
== CHAR_BIT
1176 && integer_alignment
== CHAR_BIT
) {
1183 g_string_assign(pretty
->string
, "");
1185 fprintf(pretty
->out
, "[");
1189 for (i
= 0; i
< len
; i
++) {
1190 ret
= print_sequence_field(pretty
, seq
, i
,
1191 is_string
, print_names
);
1192 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1199 if (pretty
->use_colors
) {
1200 fputs(COLOR_STRING_VALUE
, pretty
->out
);
1202 print_escape_string(pretty
, pretty
->string
->str
);
1203 if (pretty
->use_colors
) {
1204 fputs(COLOR_RST
, pretty
->out
);
1207 fprintf(pretty
->out
, " ]");
1210 bt_put(length_field
);
1217 enum bt_component_status
print_variant(struct pretty_component
*pretty
,
1218 struct bt_ctf_field
*variant
, bool print_names
)
1220 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1221 struct bt_ctf_field
*field
= NULL
;
1223 field
= bt_ctf_field_variant_get_current_field(variant
);
1225 ret
= BT_COMPONENT_STATUS_ERROR
;
1228 fprintf(pretty
->out
, "{ ");
1232 struct bt_ctf_field
*tag_field
= NULL
;
1233 const char *tag_choice
;
1234 struct bt_ctf_field_type_enumeration_mapping_iterator
*iter
;
1236 tag_field
= bt_ctf_field_variant_get_tag(variant
);
1238 ret
= BT_COMPONENT_STATUS_ERROR
;
1242 iter
= bt_ctf_field_enumeration_get_mappings(tag_field
);
1245 ret
= BT_COMPONENT_STATUS_ERROR
;
1250 bt_ctf_field_type_enumeration_mapping_iterator_get_signed(
1251 iter
, &tag_choice
, NULL
, NULL
);
1255 ret
= BT_COMPONENT_STATUS_ERROR
;
1258 print_field_name_equal(pretty
, rem_(tag_choice
));
1262 ret
= print_field(pretty
, field
, print_names
, NULL
, 0);
1263 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1267 fprintf(pretty
->out
, " }");
1274 enum bt_component_status
print_field(struct pretty_component
*pretty
,
1275 struct bt_ctf_field
*field
, bool print_names
,
1276 GQuark
*filter_fields
, int filter_array_len
)
1278 enum bt_ctf_field_type_id type_id
;
1280 type_id
= bt_ctf_field_get_type_id(field
);
1282 case CTF_TYPE_INTEGER
:
1283 return print_integer(pretty
, field
);
1284 case CTF_TYPE_FLOAT
:
1288 if (bt_ctf_field_floating_point_get_value(field
, &v
)) {
1289 return BT_COMPONENT_STATUS_ERROR
;
1291 if (pretty
->use_colors
) {
1292 fputs(COLOR_NUMBER_VALUE
, pretty
->out
);
1294 fprintf(pretty
->out
, "%g", v
);
1295 if (pretty
->use_colors
) {
1296 fputs(COLOR_RST
, pretty
->out
);
1298 return BT_COMPONENT_STATUS_OK
;
1301 return print_enum(pretty
, field
);
1302 case CTF_TYPE_STRING
:
1303 if (pretty
->use_colors
) {
1304 fputs(COLOR_STRING_VALUE
, pretty
->out
);
1306 print_escape_string(pretty
, bt_ctf_field_string_get_value(field
));
1307 if (pretty
->use_colors
) {
1308 fputs(COLOR_RST
, pretty
->out
);
1310 return BT_COMPONENT_STATUS_OK
;
1311 case CTF_TYPE_STRUCT
:
1312 return print_struct(pretty
, field
, print_names
, filter_fields
,
1314 case CTF_TYPE_UNTAGGED_VARIANT
:
1315 case CTF_TYPE_VARIANT
:
1316 return print_variant(pretty
, field
, print_names
);
1317 case CTF_TYPE_ARRAY
:
1318 return print_array(pretty
, field
, print_names
);
1319 case CTF_TYPE_SEQUENCE
:
1320 return print_sequence(pretty
, field
, print_names
);
1322 fprintf(pretty
->err
, "[error] Unknown type id: %d\n", (int) type_id
);
1323 return BT_COMPONENT_STATUS_ERROR
;
1328 enum bt_component_status
print_stream_packet_context(struct pretty_component
*pretty
,
1329 struct bt_ctf_event
*event
)
1331 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1332 struct bt_ctf_packet
*packet
= NULL
;
1333 struct bt_ctf_field
*main_field
= NULL
;
1335 packet
= bt_ctf_event_get_packet(event
);
1337 ret
= BT_COMPONENT_STATUS_ERROR
;
1340 main_field
= bt_ctf_packet_get_context(packet
);
1344 if (!pretty
->start_line
) {
1345 fputs(", ", pretty
->out
);
1347 pretty
->start_line
= false;
1348 if (pretty
->options
.print_scope_field_names
) {
1349 print_name_equal(pretty
, "stream.packet.context");
1351 ret
= print_field(pretty
, main_field
,
1352 pretty
->options
.print_context_field_names
,
1353 stream_packet_context_quarks
,
1354 STREAM_PACKET_CONTEXT_QUARKS_LEN
);
1362 enum bt_component_status
print_event_header_raw(struct pretty_component
*pretty
,
1363 struct bt_ctf_event
*event
)
1365 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1366 struct bt_ctf_field
*main_field
= NULL
;
1368 main_field
= bt_ctf_event_get_header(event
);
1372 if (!pretty
->start_line
) {
1373 fputs(", ", pretty
->out
);
1375 pretty
->start_line
= false;
1376 if (pretty
->options
.print_scope_field_names
) {
1377 print_name_equal(pretty
, "stream.event.header");
1379 ret
= print_field(pretty
, main_field
,
1380 pretty
->options
.print_header_field_names
, NULL
, 0);
1387 enum bt_component_status
print_stream_event_context(struct pretty_component
*pretty
,
1388 struct bt_ctf_event
*event
)
1390 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1391 struct bt_ctf_field
*main_field
= NULL
;
1393 main_field
= bt_ctf_event_get_stream_event_context(event
);
1397 if (!pretty
->start_line
) {
1398 fputs(", ", pretty
->out
);
1400 pretty
->start_line
= false;
1401 if (pretty
->options
.print_scope_field_names
) {
1402 print_name_equal(pretty
, "stream.event.context");
1404 ret
= print_field(pretty
, main_field
,
1405 pretty
->options
.print_context_field_names
, NULL
, 0);
1412 enum bt_component_status
print_event_context(struct pretty_component
*pretty
,
1413 struct bt_ctf_event
*event
)
1415 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1416 struct bt_ctf_field
*main_field
= NULL
;
1418 main_field
= bt_ctf_event_get_event_context(event
);
1422 if (!pretty
->start_line
) {
1423 fputs(", ", pretty
->out
);
1425 pretty
->start_line
= false;
1426 if (pretty
->options
.print_scope_field_names
) {
1427 print_name_equal(pretty
, "event.context");
1429 ret
= print_field(pretty
, main_field
,
1430 pretty
->options
.print_context_field_names
, NULL
, 0);
1437 enum bt_component_status
print_event_payload(struct pretty_component
*pretty
,
1438 struct bt_ctf_event
*event
)
1440 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1441 struct bt_ctf_field
*main_field
= NULL
;
1443 main_field
= bt_ctf_event_get_payload_field(event
);
1447 if (!pretty
->start_line
) {
1448 fputs(", ", pretty
->out
);
1450 pretty
->start_line
= false;
1451 if (pretty
->options
.print_scope_field_names
) {
1452 print_name_equal(pretty
, "event.fields");
1454 ret
= print_field(pretty
, main_field
,
1455 pretty
->options
.print_payload_field_names
, NULL
, 0);
1462 enum bt_component_status
pretty_print_event(struct pretty_component
*pretty
,
1463 struct bt_notification
*event_notif
)
1465 enum bt_component_status ret
;
1466 struct bt_ctf_event
*event
=
1467 bt_notification_event_get_event(event_notif
);
1468 struct bt_clock_class_priority_map
*cc_prio_map
=
1469 bt_notification_event_get_clock_class_priority_map(event_notif
);
1472 assert(cc_prio_map
);
1473 pretty
->start_line
= true;
1474 ret
= print_event_header(pretty
, event
, cc_prio_map
);
1475 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1479 ret
= print_stream_packet_context(pretty
, event
);
1480 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1484 if (pretty
->options
.verbose
) {
1485 ret
= print_event_header_raw(pretty
, event
);
1486 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1491 ret
= print_stream_event_context(pretty
, event
);
1492 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1496 ret
= print_event_context(pretty
, event
);
1497 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1501 ret
= print_event_payload(pretty
, event
);
1502 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1506 fputc('\n', pretty
->out
);
1509 bt_put(cc_prio_map
);