tap-driver.sh: flush stdout after each test result
[babeltrace.git] / plugins / text / pretty / print.c
CommitLineData
af9a82eb 1/*
af9a82eb 2 * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
f504043c 3 * Copyright 2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
af9a82eb
JG
4 *
5 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25
3fadfbc0
MJ
26#include <babeltrace2/babeltrace.h>
27#include <babeltrace2/bitfield-internal.h>
28#include <babeltrace2/common-internal.h>
29#include <babeltrace2/compat/time-internal.h>
30#include <babeltrace2/assert-internal.h>
6a18b281 31#include <inttypes.h>
93a4161c 32#include <ctype.h>
3228cc1d 33#include "pretty.h"
af9a82eb 34
1556a1af
JG
35#define NSEC_PER_SEC 1000000000LL
36
5280f742 37#define COLOR_NAME BT_COMMON_COLOR_BOLD
08899d39 38#define COLOR_FIELD_NAME BT_COMMON_COLOR_FG_CYAN
5280f742
PP
39#define COLOR_RST BT_COMMON_COLOR_RESET
40#define COLOR_STRING_VALUE BT_COMMON_COLOR_BOLD
41#define COLOR_NUMBER_VALUE BT_COMMON_COLOR_BOLD
42#define COLOR_ENUM_MAPPING_NAME BT_COMMON_COLOR_BOLD
43#define COLOR_UNKNOWN BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_RED
08899d39 44#define COLOR_EVENT_NAME BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_MAGENTA
5280f742 45#define COLOR_TIMESTAMP BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_YELLOW
ad96d936 46
af9a82eb
JG
47struct timestamp {
48 int64_t real_timestamp; /* Relative to UNIX epoch. */
605e1019 49 uint64_t clock_snapshot; /* In cycles. */
af9a82eb
JG
50};
51
6a18b281 52static
d94d92ac 53int print_field(struct pretty_component *pretty,
b19ff26f 54 const bt_field *field, bool print_names,
2b4c4a7c 55 GQuark *filters_fields, int filter_array_len);
6a18b281 56
ad96d936 57static
3228cc1d 58void print_name_equal(struct pretty_component *pretty, const char *name)
ad96d936 59{
3228cc1d 60 if (pretty->use_colors) {
5280f742
PP
61 g_string_append_printf(pretty->string, "%s%s%s = ", COLOR_NAME,
62 name, COLOR_RST);
ad96d936 63 } else {
5280f742 64 g_string_append_printf(pretty->string, "%s = ", name);
ad96d936
PP
65 }
66}
67
68static
3228cc1d 69void print_field_name_equal(struct pretty_component *pretty, const char *name)
ad96d936 70{
3228cc1d 71 if (pretty->use_colors) {
5280f742
PP
72 g_string_append_printf(pretty->string, "%s%s%s = ",
73 COLOR_FIELD_NAME, name, COLOR_RST);
ad96d936 74 } else {
5280f742 75 g_string_append_printf(pretty->string, "%s = ", name);
ad96d936
PP
76 }
77}
78
af9a82eb 79static
3228cc1d 80void print_timestamp_cycles(struct pretty_component *pretty,
9c202476 81 const bt_clock_snapshot *clock_snapshot, bool update_last)
af9a82eb 82{
1556a1af 83 uint64_t cycles;
1556a1af 84
605e1019 85 cycles = bt_clock_snapshot_get_value(clock_snapshot);
5280f742 86 g_string_append_printf(pretty->string, "%020" PRIu64, cycles);
3af83b5a 87
9c202476
PP
88 if (update_last) {
89 if (pretty->last_cycles_timestamp != -1ULL) {
90 pretty->delta_cycles = cycles - pretty->last_cycles_timestamp;
91 }
2c091c04 92
9c202476
PP
93 pretty->last_cycles_timestamp = cycles;
94 }
af9a82eb
JG
95}
96
97static
3228cc1d 98void print_timestamp_wall(struct pretty_component *pretty,
9c202476 99 const bt_clock_snapshot *clock_snapshot, bool update_last)
af9a82eb 100{
1556a1af 101 int ret;
1556a1af
JG
102 int64_t ts_nsec = 0; /* add configurable offset */
103 int64_t ts_sec = 0; /* add configurable offset */
104 uint64_t ts_sec_abs, ts_nsec_abs;
105 bool is_negative;
af9a82eb 106
605e1019 107 if (!clock_snapshot) {
5280f742 108 g_string_append(pretty->string, "??:??:??.?????????");
1556a1af
JG
109 return;
110 }
111
605e1019 112 ret = bt_clock_snapshot_get_ns_from_origin(clock_snapshot, &ts_nsec);
1556a1af 113 if (ret) {
5280f742
PP
114 // TODO: log, this is unexpected
115 g_string_append(pretty->string, "Error");
1556a1af
JG
116 return;
117 }
118
9c202476
PP
119 if (update_last) {
120 if (pretty->last_real_timestamp != -1ULL) {
121 pretty->delta_real_timestamp = ts_nsec - pretty->last_real_timestamp;
122 }
123
124 pretty->last_real_timestamp = ts_nsec;
3af83b5a 125 }
3af83b5a 126
1556a1af
JG
127 ts_sec += ts_nsec / NSEC_PER_SEC;
128 ts_nsec = ts_nsec % NSEC_PER_SEC;
5280f742 129
1556a1af
JG
130 if (ts_sec >= 0 && ts_nsec >= 0) {
131 is_negative = false;
132 ts_sec_abs = ts_sec;
133 ts_nsec_abs = ts_nsec;
134 } else if (ts_sec > 0 && ts_nsec < 0) {
135 is_negative = false;
136 ts_sec_abs = ts_sec - 1;
137 ts_nsec_abs = NSEC_PER_SEC + ts_nsec;
138 } else if (ts_sec == 0 && ts_nsec < 0) {
139 is_negative = true;
140 ts_sec_abs = ts_sec;
141 ts_nsec_abs = -ts_nsec;
142 } else if (ts_sec < 0 && ts_nsec > 0) {
143 is_negative = true;
144 ts_sec_abs = -(ts_sec + 1);
145 ts_nsec_abs = NSEC_PER_SEC - ts_nsec;
146 } else if (ts_sec < 0 && ts_nsec == 0) {
147 is_negative = true;
148 ts_sec_abs = -ts_sec;
149 ts_nsec_abs = ts_nsec;
150 } else { /* (ts_sec < 0 && ts_nsec < 0) */
151 is_negative = true;
152 ts_sec_abs = -ts_sec;
153 ts_nsec_abs = -ts_nsec;
154 }
155
3228cc1d 156 if (!pretty->options.clock_seconds) {
1556a1af
JG
157 struct tm tm;
158 time_t time_s = (time_t) ts_sec_abs;
159
18adbd19 160 if (is_negative && !pretty->negative_timestamp_warning_done) {
5280f742 161 // TODO: log instead
1556a1af 162 fprintf(stderr, "[warning] Fallback to [sec.ns] to print negative time value. Use --clock-seconds.\n");
18adbd19 163 pretty->negative_timestamp_warning_done = true;
1556a1af
JG
164 goto seconds;
165 }
166
3228cc1d 167 if (!pretty->options.clock_gmt) {
1556a1af
JG
168 struct tm *res;
169
58a2480d 170 res = bt_localtime_r(&time_s, &tm);
1556a1af 171 if (!res) {
5280f742 172 // TODO: log instead
1556a1af
JG
173 fprintf(stderr, "[warning] Unable to get localtime.\n");
174 goto seconds;
175 }
176 } else {
177 struct tm *res;
178
58a2480d 179 res = bt_gmtime_r(&time_s, &tm);
1556a1af 180 if (!res) {
5280f742 181 // TODO: log instead
1556a1af
JG
182 fprintf(stderr, "[warning] Unable to get gmtime.\n");
183 goto seconds;
184 }
185 }
3228cc1d 186 if (pretty->options.clock_date) {
1556a1af
JG
187 char timestr[26];
188 size_t res;
189
190 /* Print date and time */
191 res = strftime(timestr, sizeof(timestr),
4d2a94f1 192 "%Y-%m-%d ", &tm);
1556a1af 193 if (!res) {
5280f742 194 // TODO: log instead
1556a1af
JG
195 fprintf(stderr, "[warning] Unable to print ascii time.\n");
196 goto seconds;
197 }
5280f742
PP
198
199 g_string_append(pretty->string, timestr);
1556a1af 200 }
5280f742 201
1556a1af 202 /* Print time in HH:MM:SS.ns */
5280f742
PP
203 g_string_append_printf(pretty->string,
204 "%02d:%02d:%02d.%09" PRIu64, tm.tm_hour, tm.tm_min,
205 tm.tm_sec, ts_nsec_abs);
1556a1af
JG
206 goto end;
207 }
208seconds:
5280f742
PP
209 g_string_append_printf(pretty->string, "%s%" PRId64 ".%09" PRIu64,
210 is_negative ? "-" : "", ts_sec_abs, ts_nsec_abs);
1556a1af
JG
211end:
212 return;
af9a82eb
JG
213}
214
215static
d94d92ac 216int print_event_timestamp(struct pretty_component *pretty,
2c091c04 217 const bt_message *event_msg, bool *start_line)
af9a82eb 218{
3228cc1d 219 bool print_names = pretty->options.print_header_field_names;
d94d92ac 220 int ret = 0;
605e1019 221 const bt_clock_snapshot *clock_snapshot = NULL;
af9a82eb 222
81c25620
PP
223 if (!bt_message_event_borrow_stream_class_default_clock_class_const(
224 event_msg)) {
2c091c04 225 /* No default clock class: skip the timestamp without an error */
f504043c
MD
226 goto end;
227 }
d9f65f09 228
0cbc2c33 229 clock_snapshot = bt_message_event_borrow_default_clock_snapshot_const(event_msg);
af9a82eb 230
ad96d936 231 if (print_names) {
3228cc1d 232 print_name_equal(pretty, "timestamp");
ad96d936 233 } else {
5280f742 234 g_string_append(pretty->string, "[");
ad96d936 235 }
3228cc1d 236 if (pretty->use_colors) {
5280f742 237 g_string_append(pretty->string, COLOR_TIMESTAMP);
ad96d936 238 }
3228cc1d 239 if (pretty->options.print_timestamp_cycles) {
9c202476 240 print_timestamp_cycles(pretty, clock_snapshot, true);
af9a82eb 241 } else {
9c202476 242 print_timestamp_wall(pretty, clock_snapshot, true);
af9a82eb 243 }
3228cc1d 244 if (pretty->use_colors) {
5280f742 245 g_string_append(pretty->string, COLOR_RST);
ad96d936 246 }
af9a82eb 247
c3c30b08 248 if (!print_names)
5280f742 249 g_string_append(pretty->string, "] ");
c3c30b08 250
3228cc1d 251 if (pretty->options.print_delta_field) {
ad96d936 252 if (print_names) {
5280f742 253 g_string_append(pretty->string, ", ");
3228cc1d 254 print_name_equal(pretty, "delta");
ad96d936 255 } else {
5280f742 256 g_string_append(pretty->string, "(");
ad96d936 257 }
3228cc1d
PP
258 if (pretty->options.print_timestamp_cycles) {
259 if (pretty->delta_cycles == -1ULL) {
5280f742 260 g_string_append(pretty->string,
c6a871e9 261 "+??????????\?\?"); /* Not a trigraph. */
3af83b5a 262 } else {
5280f742
PP
263 g_string_append_printf(pretty->string,
264 "+%012" PRIu64, pretty->delta_cycles);
3af83b5a
MD
265 }
266 } else {
3228cc1d 267 if (pretty->delta_real_timestamp != -1ULL) {
3af83b5a 268 uint64_t delta_sec, delta_nsec, delta;
f504043c 269
3228cc1d 270 delta = pretty->delta_real_timestamp;
3af83b5a
MD
271 delta_sec = delta / NSEC_PER_SEC;
272 delta_nsec = delta % NSEC_PER_SEC;
5280f742
PP
273 g_string_append_printf(pretty->string,
274 "+%" PRIu64 ".%09" PRIu64,
3af83b5a
MD
275 delta_sec, delta_nsec);
276 } else {
5280f742 277 g_string_append(pretty->string, "+?.?????????");
3af83b5a
MD
278 }
279 }
280 if (!print_names) {
5280f742 281 g_string_append(pretty->string, ") ");
3af83b5a
MD
282 }
283 }
284 *start_line = !print_names;
f504043c 285
af9a82eb 286end:
af9a82eb
JG
287 return ret;
288}
289
6a18b281 290static
d94d92ac 291int print_event_header(struct pretty_component *pretty,
2c091c04 292 const bt_message *event_msg)
af9a82eb 293{
3228cc1d 294 bool print_names = pretty->options.print_header_field_names;
d94d92ac 295 int ret = 0;
b19ff26f
PP
296 const bt_event_class *event_class = NULL;
297 const bt_stream_class *stream_class = NULL;
298 const bt_trace_class *trace_class = NULL;
299 const bt_packet *packet = NULL;
300 const bt_stream *stream = NULL;
301 const bt_trace *trace = NULL;
2c091c04 302 const bt_event *event = bt_message_event_borrow_event_const(event_msg);
60535549 303 int dom_print = 0;
4cdfc5e8 304 bt_property_availability prop_avail;
af9a82eb 305
40f4ba76 306 event_class = bt_event_borrow_class_const(event);
40f4ba76 307 stream_class = bt_event_class_borrow_stream_class_const(event_class);
862ca4ed
PP
308 trace_class = bt_stream_class_borrow_trace_class_const(stream_class);
309 packet = bt_event_borrow_packet_const(event);
310 stream = bt_packet_borrow_stream_const(packet);
311 trace = bt_stream_borrow_trace_const(stream);
2c091c04 312 ret = print_event_timestamp(pretty, event_msg, &pretty->start_line);
d94d92ac 313 if (ret) {
af9a82eb
JG
314 goto end;
315 }
3228cc1d 316 if (pretty->options.print_trace_field) {
c3c30b08
MD
317 const char *name;
318
862ca4ed 319 name = bt_trace_get_name(trace);
c3c30b08 320 if (name) {
3228cc1d 321 if (!pretty->start_line) {
5280f742 322 g_string_append(pretty->string, ", ");
c3c30b08 323 }
c3c30b08 324 if (print_names) {
3228cc1d 325 print_name_equal(pretty, "trace");
c3c30b08 326 }
5280f742
PP
327
328 g_string_append(pretty->string, name);
329
22b7fdc6
PP
330 if (print_names) {
331 g_string_append(pretty->string, ", ");
60535549 332 }
c3c30b08
MD
333 }
334 }
3228cc1d 335 if (pretty->options.print_trace_hostname_field) {
b19ff26f 336 const bt_value *hostname_str;
c3c30b08 337
862ca4ed 338 hostname_str = bt_trace_class_borrow_environment_entry_value_by_name_const(
a82e90e8 339 trace_class, "hostname");
c3c30b08
MD
340 if (hostname_str) {
341 const char *str;
342
3228cc1d 343 if (!pretty->start_line) {
5280f742 344 g_string_append(pretty->string, ", ");
c3c30b08 345 }
c3c30b08 346 if (print_names) {
3228cc1d 347 print_name_equal(pretty, "trace:hostname");
c3c30b08 348 }
601b0d3c
PP
349 str = bt_value_string_get(hostname_str);
350 g_string_append(pretty->string, str);
60535549 351 dom_print = 1;
c3c30b08
MD
352 }
353 }
3228cc1d 354 if (pretty->options.print_trace_domain_field) {
b19ff26f 355 const bt_value *domain_str;
c3c30b08 356
862ca4ed 357 domain_str = bt_trace_class_borrow_environment_entry_value_by_name_const(
a82e90e8 358 trace_class, "domain");
c3c30b08
MD
359 if (domain_str) {
360 const char *str;
361
3228cc1d 362 if (!pretty->start_line) {
5280f742 363 g_string_append(pretty->string, ", ");
c3c30b08 364 }
c3c30b08 365 if (print_names) {
3228cc1d 366 print_name_equal(pretty, "trace:domain");
60535549 367 } else if (dom_print) {
5280f742 368 g_string_append(pretty->string, ":");
c3c30b08 369 }
601b0d3c
PP
370 str = bt_value_string_get(domain_str);
371 g_string_append(pretty->string, str);
60535549 372 dom_print = 1;
c3c30b08
MD
373 }
374 }
3228cc1d 375 if (pretty->options.print_trace_procname_field) {
b19ff26f 376 const bt_value *procname_str;
c3c30b08 377
862ca4ed 378 procname_str = bt_trace_class_borrow_environment_entry_value_by_name_const(
a82e90e8 379 trace_class, "procname");
c3c30b08
MD
380 if (procname_str) {
381 const char *str;
382
3228cc1d 383 if (!pretty->start_line) {
5280f742 384 g_string_append(pretty->string, ", ");
c3c30b08 385 }
c3c30b08 386 if (print_names) {
3228cc1d 387 print_name_equal(pretty, "trace:procname");
60535549 388 } else if (dom_print) {
5280f742 389 g_string_append(pretty->string, ":");
c3c30b08 390 }
601b0d3c
PP
391 str = bt_value_string_get(procname_str);
392 g_string_append(pretty->string, str);
60535549 393 dom_print = 1;
c3c30b08
MD
394 }
395 }
3228cc1d 396 if (pretty->options.print_trace_vpid_field) {
b19ff26f 397 const bt_value *vpid_value;
c3c30b08 398
862ca4ed 399 vpid_value = bt_trace_class_borrow_environment_entry_value_by_name_const(
a82e90e8 400 trace_class, "vpid");
c3c30b08
MD
401 if (vpid_value) {
402 int64_t value;
403
3228cc1d 404 if (!pretty->start_line) {
5280f742 405 g_string_append(pretty->string, ", ");
c3c30b08 406 }
c3c30b08 407 if (print_names) {
3228cc1d 408 print_name_equal(pretty, "trace:vpid");
60535549 409 } else if (dom_print) {
5280f742 410 g_string_append(pretty->string, ":");
c3c30b08 411 }
fdd3a2da 412 value = bt_value_signed_integer_get(vpid_value);
601b0d3c
PP
413 g_string_append_printf(pretty->string,
414 "(%" PRId64 ")", value);
60535549 415 dom_print = 1;
c3c30b08
MD
416 }
417 }
3228cc1d 418 if (pretty->options.print_loglevel_field) {
cf76ce92 419 static const char *log_level_names[] = {
50842bdc
PP
420 [ BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY ] = "TRACE_EMERG",
421 [ BT_EVENT_CLASS_LOG_LEVEL_ALERT ] = "TRACE_ALERT",
422 [ BT_EVENT_CLASS_LOG_LEVEL_CRITICAL ] = "TRACE_CRIT",
423 [ BT_EVENT_CLASS_LOG_LEVEL_ERROR ] = "TRACE_ERR",
424 [ BT_EVENT_CLASS_LOG_LEVEL_WARNING ] = "TRACE_WARNING",
425 [ BT_EVENT_CLASS_LOG_LEVEL_NOTICE ] = "TRACE_NOTICE",
426 [ BT_EVENT_CLASS_LOG_LEVEL_INFO ] = "TRACE_INFO",
427 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM ] = "TRACE_DEBUG_SYSTEM",
428 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM ] = "TRACE_DEBUG_PROGRAM",
429 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS ] = "TRACE_DEBUG_PROCESS",
430 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE ] = "TRACE_DEBUG_MODULE",
431 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT ] = "TRACE_DEBUG_UNIT",
432 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION ] = "TRACE_DEBUG_FUNCTION",
433 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE ] = "TRACE_DEBUG_LINE",
434 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG ] = "TRACE_DEBUG",
cf76ce92 435 };
4cdfc5e8 436 bt_event_class_log_level log_level;
cf76ce92
PP
437 const char *log_level_str = NULL;
438
44c440bc
PP
439 prop_avail = bt_event_class_get_log_level(event_class,
440 &log_level);
441 if (prop_avail == BT_PROPERTY_AVAILABILITY_AVAILABLE) {
cf76ce92 442 log_level_str = log_level_names[log_level];
44c440bc 443 BT_ASSERT(log_level_str);
c3c30b08 444
3228cc1d 445 if (!pretty->start_line) {
5280f742 446 g_string_append(pretty->string, ", ");
c3c30b08 447 }
c3c30b08 448 if (print_names) {
3228cc1d 449 print_name_equal(pretty, "loglevel");
60535549 450 } else if (dom_print) {
5280f742 451 g_string_append(pretty->string, ":");
c3c30b08 452 }
cf76ce92
PP
453
454 g_string_append(pretty->string, log_level_str);
455 g_string_append_printf(
456 pretty->string, " (%d)", (int) log_level);
60535549 457 dom_print = 1;
c3c30b08
MD
458 }
459 }
3228cc1d 460 if (pretty->options.print_emf_field) {
cf76ce92 461 const char *uri_str;
c3c30b08 462
50842bdc 463 uri_str = bt_event_class_get_emf_uri(event_class);
c3c30b08 464 if (uri_str) {
3228cc1d 465 if (!pretty->start_line) {
5280f742 466 g_string_append(pretty->string, ", ");
c3c30b08 467 }
c3c30b08 468 if (print_names) {
3228cc1d 469 print_name_equal(pretty, "model.emf.uri");
60535549 470 } else if (dom_print) {
5280f742 471 g_string_append(pretty->string, ":");
c3c30b08 472 }
c3c30b08 473
cf76ce92 474 g_string_append(pretty->string, uri_str);
60535549 475 dom_print = 1;
c3c30b08
MD
476 }
477 }
60535549 478 if (dom_print && !print_names) {
5280f742 479 g_string_append(pretty->string, " ");
60535549 480 }
3228cc1d 481 if (!pretty->start_line) {
5280f742 482 g_string_append(pretty->string, ", ");
c3c30b08 483 }
3228cc1d 484 pretty->start_line = true;
6a18b281 485 if (print_names) {
3228cc1d 486 print_name_equal(pretty, "name");
ad96d936 487 }
3228cc1d 488 if (pretty->use_colors) {
5280f742 489 g_string_append(pretty->string, COLOR_EVENT_NAME);
6a18b281 490 }
50842bdc 491 g_string_append(pretty->string, bt_event_class_get_name(event_class));
3228cc1d 492 if (pretty->use_colors) {
5280f742 493 g_string_append(pretty->string, COLOR_RST);
ad96d936 494 }
60535549 495 if (!print_names) {
5280f742 496 g_string_append(pretty->string, ": ");
60535549 497 } else {
5280f742 498 g_string_append(pretty->string, ", ");
60535549 499 }
a82e90e8 500
af9a82eb 501end:
6a18b281
MD
502 return ret;
503}
504
505static
d94d92ac 506int print_integer(struct pretty_component *pretty,
b19ff26f 507 const bt_field *field)
6a18b281 508{
d94d92ac 509 int ret = 0;
4cdfc5e8 510 bt_field_class_integer_preferred_display_base base;
b19ff26f 511 const bt_field_class *int_fc;
6a18b281
MD
512 union {
513 uint64_t u;
514 int64_t s;
515 } v;
ad96d936 516 bool rst_color = false;
4cdfc5e8 517 bt_field_class_type ft_type;
6a18b281 518
40f4ba76 519 int_fc = bt_field_borrow_class_const(field);
5cd6d0e5 520 BT_ASSERT(int_fc);
864cad70
PP
521 ft_type = bt_field_get_class_type(field);
522 if (ft_type == BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER ||
523 ft_type == BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION) {
44c440bc 524 v.u = bt_field_unsigned_integer_get_value(field);
6a18b281 525 } else {
44c440bc 526 v.s = bt_field_signed_integer_get_value(field);
6a18b281
MD
527 }
528
3228cc1d 529 if (pretty->use_colors) {
5280f742 530 g_string_append(pretty->string, COLOR_NUMBER_VALUE);
ad96d936
PP
531 rst_color = true;
532 }
533
5cd6d0e5 534 base = bt_field_class_integer_get_preferred_display_base(int_fc);
6a18b281 535 switch (base) {
5cd6d0e5 536 case BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY:
6a18b281
MD
537 {
538 int bitnr, len;
539
5cd6d0e5 540 len = bt_field_class_integer_get_field_value_range(int_fc);
5280f742 541 g_string_append(pretty->string, "0b");
7f140ae8 542 _bt_safe_lshift(v.u, 64 - len);
6a18b281 543 for (bitnr = 0; bitnr < len; bitnr++) {
5280f742 544 g_string_append_printf(pretty->string, "%u", (v.u & (1ULL << 63)) ? 1 : 0);
7f140ae8 545 _bt_safe_lshift(v.u, 1);
6a18b281
MD
546 }
547 break;
548 }
5cd6d0e5 549 case BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL:
6a18b281 550 {
864cad70
PP
551 if (ft_type == BT_FIELD_CLASS_TYPE_SIGNED_INTEGER ||
552 ft_type == BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION) {
6a18b281
MD
553 int len;
554
5cd6d0e5
PP
555 len = bt_field_class_integer_get_field_value_range(
556 int_fc);
6a18b281
MD
557 if (len < 64) {
558 size_t rounded_len;
559
f6ccaed9 560 BT_ASSERT(len != 0);
6a18b281
MD
561 /* Round length to the nearest 3-bit */
562 rounded_len = (((len - 1) / 3) + 1) * 3;
563 v.u &= ((uint64_t) 1 << rounded_len) - 1;
564 }
565 }
566
5280f742 567 g_string_append_printf(pretty->string, "0%" PRIo64, v.u);
6a18b281
MD
568 break;
569 }
5cd6d0e5 570 case BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL:
864cad70
PP
571 if (ft_type == BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER ||
572 ft_type == BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION) {
5280f742 573 g_string_append_printf(pretty->string, "%" PRIu64, v.u);
6a18b281 574 } else {
5280f742 575 g_string_append_printf(pretty->string, "%" PRId64, v.s);
6a18b281
MD
576 }
577 break;
5cd6d0e5 578 case BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL:
6a18b281
MD
579 {
580 int len;
581
5cd6d0e5 582 len = bt_field_class_integer_get_field_value_range(int_fc);
6a18b281
MD
583 if (len < 64) {
584 /* Round length to the nearest nibble */
585 uint8_t rounded_len = ((len + 3) & ~0x3);
586
587 v.u &= ((uint64_t) 1 << rounded_len) - 1;
588 }
589
5280f742 590 g_string_append_printf(pretty->string, "0x%" PRIX64, v.u);
6a18b281
MD
591 break;
592 }
593 default:
d94d92ac 594 ret = -1;
6a18b281
MD
595 goto end;
596 }
597end:
ad96d936 598 if (rst_color) {
5280f742 599 g_string_append(pretty->string, COLOR_RST);
ad96d936 600 }
6a18b281
MD
601 return ret;
602}
603
93a4161c 604static
3228cc1d 605void print_escape_string(struct pretty_component *pretty, const char *str)
93a4161c
JD
606{
607 int i;
608
5280f742
PP
609 g_string_append_c(pretty->string, '"');
610
93a4161c
JD
611 for (i = 0; i < strlen(str); i++) {
612 /* Escape sequences not recognized by iscntrl(). */
613 switch (str[i]) {
614 case '\\':
5280f742 615 g_string_append(pretty->string, "\\\\");
93a4161c
JD
616 continue;
617 case '\'':
5280f742 618 g_string_append(pretty->string, "\\\'");
93a4161c
JD
619 continue;
620 case '\"':
5280f742 621 g_string_append(pretty->string, "\\\"");
93a4161c
JD
622 continue;
623 case '\?':
5280f742 624 g_string_append(pretty->string, "\\\?");
93a4161c
JD
625 continue;
626 }
627
628 /* Standard characters. */
629 if (!iscntrl(str[i])) {
5280f742 630 g_string_append_c(pretty->string, str[i]);
93a4161c
JD
631 continue;
632 }
633
634 switch (str[i]) {
635 case '\0':
5280f742 636 g_string_append(pretty->string, "\\0");
93a4161c
JD
637 break;
638 case '\a':
5280f742 639 g_string_append(pretty->string, "\\a");
93a4161c
JD
640 break;
641 case '\b':
5280f742 642 g_string_append(pretty->string, "\\b");
93a4161c
JD
643 break;
644 case '\e':
5280f742 645 g_string_append(pretty->string, "\\e");
93a4161c
JD
646 break;
647 case '\f':
5280f742 648 g_string_append(pretty->string, "\\f");
93a4161c
JD
649 break;
650 case '\n':
5280f742 651 g_string_append(pretty->string, "\\n");
93a4161c
JD
652 break;
653 case '\r':
5280f742 654 g_string_append(pretty->string, "\\r");
93a4161c
JD
655 break;
656 case '\t':
5280f742 657 g_string_append(pretty->string, "\\t");
93a4161c
JD
658 break;
659 case '\v':
5280f742 660 g_string_append(pretty->string, "\\v");
93a4161c
JD
661 break;
662 default:
663 /* Unhandled control-sequence, print as hex. */
5280f742 664 g_string_append_printf(pretty->string, "\\x%02x", str[i]);
93a4161c
JD
665 break;
666 }
667 }
5280f742
PP
668
669 g_string_append_c(pretty->string, '"');
93a4161c
JD
670}
671
6a18b281 672static
d94d92ac 673int print_enum(struct pretty_component *pretty,
b19ff26f 674 const bt_field *field)
6a18b281 675{
d94d92ac 676 int ret = 0;
b19ff26f 677 const bt_field_class *enumeration_field_class = NULL;
5cd6d0e5 678 bt_field_class_enumeration_mapping_label_array label_array;
44c440bc
PP
679 uint64_t label_count;
680 uint64_t i;
96e8f959 681
40f4ba76 682 enumeration_field_class = bt_field_borrow_class_const(field);
5cd6d0e5 683 if (!enumeration_field_class) {
d94d92ac 684 ret = -1;
96e8f959
MD
685 goto end;
686 }
44c440bc 687
864cad70
PP
688 switch (bt_field_get_class_type(field)) {
689 case BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION:
44c440bc
PP
690 ret = bt_field_unsigned_enumeration_get_mapping_labels(field,
691 &label_array, &label_count);
692 break;
864cad70 693 case BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION:
44c440bc
PP
694 ret = bt_field_signed_enumeration_get_mapping_labels(field,
695 &label_array, &label_count);
696 break;
697 default:
698 abort();
96e8f959 699 }
44c440bc
PP
700
701 if (ret) {
d94d92ac 702 ret = -1;
96e8f959
MD
703 goto end;
704 }
44c440bc 705
83ef3205 706 g_string_append(pretty->string, "( ");
44c440bc 707 if (label_count == 0) {
83ef3205
MD
708 if (pretty->use_colors) {
709 g_string_append(pretty->string, COLOR_UNKNOWN);
710 }
711 g_string_append(pretty->string, "<unknown>");
712 if (pretty->use_colors) {
713 g_string_append(pretty->string, COLOR_RST);
714 }
715 goto skip_loop;
96e8f959 716 }
44c440bc
PP
717 for (i = 0; i < label_count; i++) {
718 const char *mapping_name = label_array[i];
96e8f959 719
55c68a1a 720 if (i != 0) {
5280f742 721 g_string_append(pretty->string, ", ");
44c440bc 722 }
3228cc1d 723 if (pretty->use_colors) {
5280f742 724 g_string_append(pretty->string, COLOR_ENUM_MAPPING_NAME);
ad96d936 725 }
3228cc1d
PP
726 print_escape_string(pretty, mapping_name);
727 if (pretty->use_colors) {
5280f742 728 g_string_append(pretty->string, COLOR_RST);
ad96d936 729 }
96e8f959 730 }
83ef3205 731skip_loop:
5280f742 732 g_string_append(pretty->string, " : container = ");
312c056a 733 ret = print_integer(pretty, field);
d94d92ac 734 if (ret != 0) {
6a18b281
MD
735 goto end;
736 }
5280f742 737 g_string_append(pretty->string, " )");
6a18b281 738end:
6a18b281
MD
739 return ret;
740}
741
2b4c4a7c 742static
3228cc1d 743int filter_field_name(struct pretty_component *pretty, const char *field_name,
2b4c4a7c
JD
744 GQuark *filter_fields, int filter_array_len)
745{
746 int i;
747 GQuark field_quark = g_quark_try_string(field_name);
748
3228cc1d 749 if (!field_quark || pretty->options.verbose) {
2b4c4a7c
JD
750 return 1;
751 }
752
753 for (i = 0; i < filter_array_len; i++) {
754 if (field_quark == filter_fields[i]) {
755 return 0;
756 }
757 }
758 return 1;
759}
760
6a18b281 761static
d94d92ac 762int print_struct_field(struct pretty_component *pretty,
b19ff26f
PP
763 const bt_field *_struct,
764 const bt_field_class *struct_class,
44c440bc 765 uint64_t i, bool print_names, uint64_t *nr_printed_fields,
2b4c4a7c 766 GQuark *filter_fields, int filter_array_len)
6a18b281 767{
d94d92ac 768 int ret = 0;
6a18b281 769 const char *field_name;
b19ff26f 770 const bt_field *field = NULL;
1e6fd1d7 771 const bt_field_class_structure_member *member;
6a18b281 772
40f4ba76 773 field = bt_field_structure_borrow_member_field_by_index_const(_struct, i);
6a18b281 774 if (!field) {
d94d92ac 775 ret = -1;
6a18b281
MD
776 goto end;
777 }
44c440bc 778
1e6fd1d7
PP
779 member = bt_field_class_structure_borrow_member_by_index_const(
780 struct_class, i);
781 field_name = bt_field_class_structure_member_get_name(member);
6a18b281 782
3228cc1d 783 if (filter_fields && !filter_field_name(pretty, field_name,
2b4c4a7c 784 filter_fields, filter_array_len)) {
d94d92ac 785 ret = 0;
2b4c4a7c
JD
786 goto end;
787 }
788
789 if (*nr_printed_fields > 0) {
5280f742 790 g_string_append(pretty->string, ", ");
6a18b281 791 } else {
5280f742 792 g_string_append(pretty->string, " ");
6a18b281
MD
793 }
794 if (print_names) {
6acddae3 795 print_field_name_equal(pretty, field_name);
6a18b281 796 }
3228cc1d 797 ret = print_field(pretty, field, print_names, NULL, 0);
2b4c4a7c 798 *nr_printed_fields += 1;
a82e90e8 799
6a18b281 800end:
6a18b281
MD
801 return ret;
802}
803
804static
d94d92ac 805int print_struct(struct pretty_component *pretty,
b19ff26f 806 const bt_field *_struct, bool print_names,
2b4c4a7c 807 GQuark *filter_fields, int filter_array_len)
6a18b281 808{
d94d92ac 809 int ret = 0;
b19ff26f 810 const bt_field_class *struct_class = NULL;
44c440bc 811 uint64_t nr_fields, i, nr_printed_fields;
6a18b281 812
40f4ba76 813 struct_class = bt_field_borrow_class_const(_struct);
5cd6d0e5 814 if (!struct_class) {
d94d92ac 815 ret = -1;
6a18b281
MD
816 goto end;
817 }
53dc85fa 818
5cd6d0e5 819 nr_fields = bt_field_class_structure_get_member_count(struct_class);
53dc85fa 820
5280f742 821 g_string_append(pretty->string, "{");
3228cc1d 822 pretty->depth++;
2b4c4a7c 823 nr_printed_fields = 0;
6a18b281 824 for (i = 0; i < nr_fields; i++) {
5cd6d0e5 825 ret = print_struct_field(pretty, _struct, struct_class, i,
2b4c4a7c
JD
826 print_names, &nr_printed_fields, filter_fields,
827 filter_array_len);
d94d92ac 828 if (ret != 0) {
6a18b281
MD
829 goto end;
830 }
831 }
3228cc1d 832 pretty->depth--;
5280f742 833 g_string_append(pretty->string, " }");
a82e90e8 834
6a18b281 835end:
6a18b281
MD
836 return ret;
837}
838
839static
d94d92ac 840int print_array_field(struct pretty_component *pretty,
b19ff26f 841 const bt_field *array, uint64_t i, bool print_names)
6a18b281 842{
b19ff26f 843 const bt_field *field = NULL;
6a18b281 844
44c440bc
PP
845 if (i != 0) {
846 g_string_append(pretty->string, ", ");
847 } else {
848 g_string_append(pretty->string, " ");
6a18b281 849 }
44c440bc
PP
850 if (print_names) {
851 g_string_append_printf(pretty->string, "[%" PRIu64 "] = ", i);
6a18b281 852 }
a82e90e8 853
40f4ba76 854 field = bt_field_array_borrow_element_field_by_index_const(array, i);
44c440bc
PP
855 BT_ASSERT(field);
856 return print_field(pretty, field, print_names, NULL, 0);
6a18b281
MD
857}
858
859static
d94d92ac 860int print_array(struct pretty_component *pretty,
b19ff26f 861 const bt_field *array, bool print_names)
6a18b281 862{
d94d92ac 863 int ret = 0;
b19ff26f 864 const bt_field_class *array_class = NULL;
44c440bc 865 uint64_t len;
6a18b281 866 uint64_t i;
6a18b281 867
40f4ba76 868 array_class = bt_field_borrow_class_const(array);
5cd6d0e5 869 if (!array_class) {
d94d92ac 870 ret = -1;
6a18b281
MD
871 goto end;
872 }
44c440bc
PP
873 len = bt_field_array_get_length(array);
874 g_string_append(pretty->string, "[");
3228cc1d 875 pretty->depth++;
6a18b281 876 for (i = 0; i < len; i++) {
44c440bc 877 ret = print_array_field(pretty, array, i, print_names);
d94d92ac 878 if (ret != 0) {
6a18b281
MD
879 goto end;
880 }
881 }
3228cc1d 882 pretty->depth--;
44c440bc 883 g_string_append(pretty->string, " ]");
a82e90e8 884
6a18b281 885end:
6a18b281
MD
886 return ret;
887}
888
889static
d94d92ac 890int print_sequence_field(struct pretty_component *pretty,
b19ff26f 891 const bt_field *seq, uint64_t i, bool print_names)
6a18b281 892{
b19ff26f 893 const bt_field *field = NULL;
6a18b281 894
44c440bc
PP
895 if (i != 0) {
896 g_string_append(pretty->string, ", ");
897 } else {
898 g_string_append(pretty->string, " ");
6a18b281 899 }
44c440bc
PP
900 if (print_names) {
901 g_string_append_printf(pretty->string, "[%" PRIu64 "] = ", i);
6a18b281 902 }
a82e90e8 903
40f4ba76 904 field = bt_field_array_borrow_element_field_by_index_const(seq, i);
44c440bc
PP
905 BT_ASSERT(field);
906 return print_field(pretty, field, print_names, NULL, 0);
6a18b281
MD
907}
908
909static
d94d92ac 910int print_sequence(struct pretty_component *pretty,
b19ff26f 911 const bt_field *seq, bool print_names)
6a18b281 912{
d94d92ac 913 int ret = 0;
44c440bc 914 uint64_t len;
6a18b281 915 uint64_t i;
6a18b281 916
44c440bc 917 len = bt_field_array_get_length(seq);
44c440bc 918 g_string_append(pretty->string, "[");
6a18b281 919
3228cc1d 920 pretty->depth++;
6a18b281 921 for (i = 0; i < len; i++) {
44c440bc 922 ret = print_sequence_field(pretty, seq, i, print_names);
d94d92ac 923 if (ret != 0) {
6a18b281
MD
924 goto end;
925 }
926 }
3228cc1d 927 pretty->depth--;
44c440bc 928 g_string_append(pretty->string, " ]");
a82e90e8 929
6a18b281 930end:
6a18b281
MD
931 return ret;
932}
933
934static
d94d92ac 935int print_variant(struct pretty_component *pretty,
b19ff26f 936 const bt_field *variant, bool print_names)
6a18b281 937{
d94d92ac 938 int ret = 0;
b19ff26f 939 const bt_field *field = NULL;
6a18b281 940
40f4ba76 941 field = bt_field_variant_borrow_selected_option_field_const(variant);
44c440bc 942 BT_ASSERT(field);
5280f742 943 g_string_append(pretty->string, "{ ");
3228cc1d 944 pretty->depth++;
6a18b281 945 if (print_names) {
44c440bc
PP
946 // TODO: find tag's name using field path
947 // print_field_name_equal(pretty, tag_choice);
6a18b281 948 }
3228cc1d 949 ret = print_field(pretty, field, print_names, NULL, 0);
d94d92ac 950 if (ret != 0) {
6a18b281
MD
951 goto end;
952 }
3228cc1d 953 pretty->depth--;
5280f742 954 g_string_append(pretty->string, " }");
a82e90e8 955
6a18b281 956end:
6a18b281
MD
957 return ret;
958}
959
960static
d94d92ac 961int print_field(struct pretty_component *pretty,
b19ff26f 962 const bt_field *field, bool print_names,
2b4c4a7c 963 GQuark *filter_fields, int filter_array_len)
6a18b281 964{
4cdfc5e8 965 bt_field_class_type class_id;
6a18b281 966
864cad70 967 class_id = bt_field_get_class_type(field);
5cd6d0e5 968 switch (class_id) {
864cad70
PP
969 case BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER:
970 case BT_FIELD_CLASS_TYPE_SIGNED_INTEGER:
3228cc1d 971 return print_integer(pretty, field);
864cad70 972 case BT_FIELD_CLASS_TYPE_REAL:
6a18b281
MD
973 {
974 double v;
975
44c440bc 976 v = bt_field_real_get_value(field);
3228cc1d 977 if (pretty->use_colors) {
5280f742 978 g_string_append(pretty->string, COLOR_NUMBER_VALUE);
ad96d936 979 }
5280f742 980 g_string_append_printf(pretty->string, "%g", v);
3228cc1d 981 if (pretty->use_colors) {
5280f742 982 g_string_append(pretty->string, COLOR_RST);
ad96d936 983 }
d94d92ac 984 return 0;
6a18b281 985 }
864cad70
PP
986 case BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION:
987 case BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION:
3228cc1d 988 return print_enum(pretty, field);
864cad70 989 case BT_FIELD_CLASS_TYPE_STRING:
95a518bf
JG
990 {
991 const char *str;
992
50842bdc 993 str = bt_field_string_get_value(field);
95a518bf 994 if (!str) {
d94d92ac 995 return -1;
95a518bf
JG
996 }
997
3228cc1d 998 if (pretty->use_colors) {
5280f742 999 g_string_append(pretty->string, COLOR_STRING_VALUE);
ad96d936 1000 }
95a518bf 1001 print_escape_string(pretty, str);
3228cc1d 1002 if (pretty->use_colors) {
5280f742 1003 g_string_append(pretty->string, COLOR_RST);
ad96d936 1004 }
d94d92ac 1005 return 0;
95a518bf 1006 }
864cad70 1007 case BT_FIELD_CLASS_TYPE_STRUCTURE:
3228cc1d 1008 return print_struct(pretty, field, print_names, filter_fields,
2b4c4a7c 1009 filter_array_len);
864cad70 1010 case BT_FIELD_CLASS_TYPE_VARIANT:
3228cc1d 1011 return print_variant(pretty, field, print_names);
864cad70 1012 case BT_FIELD_CLASS_TYPE_STATIC_ARRAY:
3228cc1d 1013 return print_array(pretty, field, print_names);
864cad70 1014 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY:
3228cc1d 1015 return print_sequence(pretty, field, print_names);
6a18b281 1016 default:
5280f742 1017 // TODO: log instead
5cd6d0e5 1018 fprintf(pretty->err, "[error] Unknown type id: %d\n", (int) class_id);
d94d92ac 1019 return -1;
6a18b281
MD
1020 }
1021}
1022
1023static
d94d92ac 1024int print_stream_packet_context(struct pretty_component *pretty,
b19ff26f 1025 const bt_event *event)
6a18b281 1026{
d94d92ac 1027 int ret = 0;
b19ff26f
PP
1028 const bt_packet *packet = NULL;
1029 const bt_field *main_field = NULL;
6a18b281 1030
40f4ba76 1031 packet = bt_event_borrow_packet_const(event);
6a18b281 1032 if (!packet) {
d94d92ac 1033 ret = -1;
6a18b281
MD
1034 goto end;
1035 }
40f4ba76 1036 main_field = bt_packet_borrow_context_field_const(packet);
6a18b281 1037 if (!main_field) {
6a18b281
MD
1038 goto end;
1039 }
3228cc1d 1040 if (!pretty->start_line) {
5280f742 1041 g_string_append(pretty->string, ", ");
6e1bc0df 1042 }
3228cc1d
PP
1043 pretty->start_line = false;
1044 if (pretty->options.print_scope_field_names) {
1045 print_name_equal(pretty, "stream.packet.context");
6a18b281 1046 }
3228cc1d
PP
1047 ret = print_field(pretty, main_field,
1048 pretty->options.print_context_field_names,
2b4c4a7c
JD
1049 stream_packet_context_quarks,
1050 STREAM_PACKET_CONTEXT_QUARKS_LEN);
a82e90e8 1051
6a18b281 1052end:
6a18b281
MD
1053 return ret;
1054}
1055
6a18b281 1056static
d94d92ac 1057int print_stream_event_context(struct pretty_component *pretty,
b19ff26f 1058 const bt_event *event)
6a18b281 1059{
d94d92ac 1060 int ret = 0;
b19ff26f 1061 const bt_field *main_field = NULL;
6a18b281 1062
40f4ba76 1063 main_field = bt_event_borrow_common_context_field_const(event);
6a18b281 1064 if (!main_field) {
6a18b281
MD
1065 goto end;
1066 }
3228cc1d 1067 if (!pretty->start_line) {
5280f742 1068 g_string_append(pretty->string, ", ");
6e1bc0df 1069 }
3228cc1d
PP
1070 pretty->start_line = false;
1071 if (pretty->options.print_scope_field_names) {
1072 print_name_equal(pretty, "stream.event.context");
6a18b281 1073 }
3228cc1d
PP
1074 ret = print_field(pretty, main_field,
1075 pretty->options.print_context_field_names, NULL, 0);
a82e90e8 1076
6a18b281 1077end:
6a18b281
MD
1078 return ret;
1079}
1080
1081static
d94d92ac 1082int print_event_context(struct pretty_component *pretty,
b19ff26f 1083 const bt_event *event)
6a18b281 1084{
d94d92ac 1085 int ret = 0;
b19ff26f 1086 const bt_field *main_field = NULL;
6a18b281 1087
40f4ba76 1088 main_field = bt_event_borrow_specific_context_field_const(event);
6a18b281 1089 if (!main_field) {
6a18b281
MD
1090 goto end;
1091 }
3228cc1d 1092 if (!pretty->start_line) {
5280f742 1093 g_string_append(pretty->string, ", ");
6e1bc0df 1094 }
3228cc1d
PP
1095 pretty->start_line = false;
1096 if (pretty->options.print_scope_field_names) {
1097 print_name_equal(pretty, "event.context");
6a18b281 1098 }
3228cc1d
PP
1099 ret = print_field(pretty, main_field,
1100 pretty->options.print_context_field_names, NULL, 0);
a82e90e8 1101
6a18b281 1102end:
6a18b281
MD
1103 return ret;
1104}
1105
1106static
d94d92ac 1107int print_event_payload(struct pretty_component *pretty,
b19ff26f 1108 const bt_event *event)
6a18b281 1109{
d94d92ac 1110 int ret = 0;
b19ff26f 1111 const bt_field *main_field = NULL;
6a18b281 1112
40f4ba76 1113 main_field = bt_event_borrow_payload_field_const(event);
6a18b281 1114 if (!main_field) {
6a18b281
MD
1115 goto end;
1116 }
3228cc1d 1117 if (!pretty->start_line) {
5280f742 1118 g_string_append(pretty->string, ", ");
6e1bc0df 1119 }
3228cc1d
PP
1120 pretty->start_line = false;
1121 if (pretty->options.print_scope_field_names) {
1122 print_name_equal(pretty, "event.fields");
6a18b281 1123 }
3228cc1d
PP
1124 ret = print_field(pretty, main_field,
1125 pretty->options.print_payload_field_names, NULL, 0);
a82e90e8 1126
6a18b281 1127end:
af9a82eb
JG
1128 return ret;
1129}
1130
08899d39 1131static
0f6bea4e 1132int flush_buf(FILE *stream, struct pretty_component *pretty)
08899d39
PP
1133{
1134 int ret = 0;
1135
1136 if (pretty->string->len == 0) {
1137 goto end;
1138 }
1139
0f6bea4e 1140 if (fwrite(pretty->string->str, pretty->string->len, 1, stream) != 1) {
08899d39
PP
1141 ret = -1;
1142 }
1143
1144end:
1145 return ret;
1146}
1147
af9a82eb 1148BT_HIDDEN
d94d92ac 1149int pretty_print_event(struct pretty_component *pretty,
d6e69534 1150 const bt_message *event_msg)
af9a82eb 1151{
d94d92ac 1152 int ret;
b19ff26f 1153 const bt_event *event =
d6e69534 1154 bt_message_event_borrow_event_const(event_msg);
af9a82eb 1155
f6ccaed9 1156 BT_ASSERT(event);
3228cc1d 1157 pretty->start_line = true;
5280f742 1158 g_string_assign(pretty->string, "");
2c091c04 1159 ret = print_event_header(pretty, event_msg);
d94d92ac 1160 if (ret != 0) {
af9a82eb
JG
1161 goto end;
1162 }
6a18b281 1163
3228cc1d 1164 ret = print_stream_packet_context(pretty, event);
d94d92ac 1165 if (ret != 0) {
6a18b281
MD
1166 goto end;
1167 }
6a18b281 1168
3228cc1d 1169 ret = print_stream_event_context(pretty, event);
d94d92ac 1170 if (ret != 0) {
6a18b281
MD
1171 goto end;
1172 }
6a18b281 1173
3228cc1d 1174 ret = print_event_context(pretty, event);
d94d92ac 1175 if (ret != 0) {
6a18b281
MD
1176 goto end;
1177 }
6a18b281 1178
3228cc1d 1179 ret = print_event_payload(pretty, event);
d94d92ac 1180 if (ret != 0) {
6a18b281
MD
1181 goto end;
1182 }
af9a82eb 1183
5280f742 1184 g_string_append_c(pretty->string, '\n');
0f6bea4e 1185 if (flush_buf(pretty->out, pretty)) {
d94d92ac 1186 ret = -1;
5280f742
PP
1187 goto end;
1188 }
1189
af9a82eb
JG
1190end:
1191 return ret;
1192}
0f6bea4e
PP
1193
1194static
8e53bed4
PP
1195int print_discarded_elements_msg(struct pretty_component *pretty,
1196 const bt_stream *stream,
1197 const bt_clock_snapshot *begin_clock_snapshot,
1198 const bt_clock_snapshot *end_clock_snapshot,
0f6bea4e
PP
1199 uint64_t count, const char *elem_type)
1200{
d94d92ac 1201 int ret = 0;
b19ff26f
PP
1202 const bt_stream_class *stream_class = NULL;
1203 const bt_trace *trace = NULL;
0f6bea4e
PP
1204 const char *stream_name;
1205 const char *trace_name;
8e53bed4 1206 bt_uuid trace_uuid;
0f6bea4e
PP
1207 int64_t stream_class_id;
1208 int64_t stream_id;
697f479d 1209 const char *init_msg;
0f6bea4e
PP
1210
1211 /* Stream name */
0f6bea4e 1212 stream_name = bt_stream_get_name(stream);
8e53bed4
PP
1213 if (!stream_name) {
1214 stream_name = "(unknown)";
1215 }
0f6bea4e
PP
1216
1217 /* Stream class ID */
40f4ba76 1218 stream_class = bt_stream_borrow_class_const(stream);
0f6bea4e
PP
1219 BT_ASSERT(stream_class);
1220 stream_class_id = bt_stream_class_get_id(stream_class);
1221
1222 /* Stream ID */
1223 stream_id = bt_stream_get_id(stream);
1224
1225 /* Trace name */
8e53bed4 1226 trace = bt_stream_borrow_trace_const(stream);
0f6bea4e
PP
1227 BT_ASSERT(trace);
1228 trace_name = bt_trace_get_name(trace);
1229 if (!trace_name) {
1230 trace_name = "(unknown)";
1231 }
1232
1233 /* Trace UUID */
8e53bed4
PP
1234 trace_uuid = bt_trace_class_get_uuid(
1235 bt_trace_borrow_class_const(trace));
0f6bea4e
PP
1236
1237 /* Format message */
1238 g_string_assign(pretty->string, "");
697f479d
PP
1239
1240 if (count == UINT64_C(-1)) {
1241 init_msg = "Tracer may have discarded";
1242 } else {
1243 init_msg = "Tracer discarded";
1244 }
1245
0f6bea4e 1246 g_string_append_printf(pretty->string,
697f479d 1247 "%s%sWARNING%s%s: %s ",
0f6bea4e
PP
1248 bt_common_color_fg_yellow(),
1249 bt_common_color_bold(),
1250 bt_common_color_reset(),
697f479d 1251 bt_common_color_fg_yellow(), init_msg);
8e53bed4
PP
1252
1253 if (count == UINT64_C(-1)) {
697f479d 1254 g_string_append_printf(pretty->string, "%ss", elem_type);
8e53bed4
PP
1255 } else {
1256 g_string_append_printf(pretty->string,
1257 "%" PRIu64 " %s%s", count, elem_type,
1258 count == 1 ? "" : "s");
1259 }
0f6bea4e 1260
3f2f6b21
PP
1261 g_string_append_c(pretty->string, ' ');
1262
605e1019 1263 if (begin_clock_snapshot && end_clock_snapshot) {
3f2f6b21 1264 g_string_append(pretty->string, "between [");
9c202476 1265 print_timestamp_wall(pretty, begin_clock_snapshot, false);
0f6bea4e 1266 g_string_append(pretty->string, "] and [");
9c202476 1267 print_timestamp_wall(pretty, end_clock_snapshot, false);
0f6bea4e
PP
1268 g_string_append(pretty->string, "]");
1269 } else {
1270 g_string_append(pretty->string, "(unknown time range)");
1271 }
1272
1273 g_string_append_printf(pretty->string, " in trace \"%s\" ", trace_name);
1274
1275 if (trace_uuid) {
1276 g_string_append_printf(pretty->string,
1277 "(UUID: %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x) ",
1278 trace_uuid[0],
1279 trace_uuid[1],
1280 trace_uuid[2],
1281 trace_uuid[3],
1282 trace_uuid[4],
1283 trace_uuid[5],
1284 trace_uuid[6],
1285 trace_uuid[7],
1286 trace_uuid[8],
1287 trace_uuid[9],
1288 trace_uuid[10],
1289 trace_uuid[11],
1290 trace_uuid[12],
1291 trace_uuid[13],
1292 trace_uuid[14],
1293 trace_uuid[15]);
1294 } else {
1295 g_string_append(pretty->string, "(no UUID) ");
1296 }
1297
1298 g_string_append_printf(pretty->string,
8e53bed4 1299 "within stream \"%s\" (stream class ID: %" PRIu64 ", ",
0f6bea4e
PP
1300 stream_name, stream_class_id);
1301
1302 if (stream_id >= 0) {
1303 g_string_append_printf(pretty->string,
8e53bed4 1304 "stream ID: %" PRIu64, stream_id);
0f6bea4e
PP
1305 } else {
1306 g_string_append(pretty->string, "no stream ID");
1307 }
1308
1309 g_string_append_printf(pretty->string, ").%s\n",
1310 bt_common_color_reset());
1311
1312 /*
1313 * Print to standard error stream to remain backward compatible
1314 * with Babeltrace 1.
1315 */
1316 if (flush_buf(stderr, pretty)) {
d94d92ac 1317 ret = -1;
0f6bea4e
PP
1318 }
1319
1320 return ret;
1321}
1322
1323BT_HIDDEN
8e53bed4
PP
1324int pretty_print_discarded_items(struct pretty_component *pretty,
1325 const bt_message *msg)
0f6bea4e 1326{
8e53bed4
PP
1327 const bt_clock_snapshot *begin = NULL;
1328 const bt_clock_snapshot *end = NULL;
1329 const bt_stream *stream;
1330 const bt_stream_class *stream_class;
1331 uint64_t count = UINT64_C(-1);
1332 const char *elem_type;
1333
1334 switch (bt_message_get_type(msg)) {
1335 case BT_MESSAGE_TYPE_DISCARDED_EVENTS:
1336 stream = bt_message_discarded_events_borrow_stream_const(msg);
1337
1338 if (bt_message_discarded_events_get_count(msg, &count) ==
1339 BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE) {
1340 count = UINT64_C(-1);
0f6bea4e 1341 }
8e53bed4
PP
1342
1343 elem_type = "event";
1344 break;
1345 case BT_MESSAGE_TYPE_DISCARDED_PACKETS:
1346 stream = bt_message_discarded_packets_borrow_stream_const(msg);
1347
1348 if (bt_message_discarded_packets_get_count(msg, &count) ==
1349 BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE) {
1350 count = UINT64_C(-1);
1351 }
1352
1353 elem_type = "packet";
1354 break;
1355 default:
1356 abort();
0f6bea4e
PP
1357 }
1358
8e53bed4
PP
1359 BT_ASSERT(stream);
1360 stream_class = bt_stream_borrow_class_const(stream);
1361
2e90378a
PP
1362 switch (bt_message_get_type(msg)) {
1363 case BT_MESSAGE_TYPE_DISCARDED_EVENTS:
1364 if (bt_stream_class_discarded_events_have_default_clock_snapshots(
1365 stream_class)) {
9b24b6aa 1366 begin = bt_message_discarded_events_borrow_beginning_default_clock_snapshot_const(
0cbc2c33 1367 msg);
9b24b6aa 1368 end = bt_message_discarded_events_borrow_end_default_clock_snapshot_const(
0cbc2c33 1369 msg);
2e90378a
PP
1370 }
1371
1372 break;
1373 case BT_MESSAGE_TYPE_DISCARDED_PACKETS:
1374 if (bt_stream_class_discarded_packets_have_default_clock_snapshots(
1375 stream_class)) {
9b24b6aa 1376 begin = bt_message_discarded_packets_borrow_beginning_default_clock_snapshot_const(
0cbc2c33 1377 msg);
9b24b6aa 1378 end = bt_message_discarded_packets_borrow_end_default_clock_snapshot_const(
0cbc2c33 1379 msg);
0f6bea4e 1380 }
2e90378a
PP
1381
1382 break;
1383 default:
1384 abort();
0f6bea4e
PP
1385 }
1386
8e53bed4
PP
1387 print_discarded_elements_msg(pretty, stream, begin, end,
1388 count, elem_type);
44c440bc 1389 return 0;
0f6bea4e 1390}
This page took 0.124715 seconds and 4 git commands to generate.