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