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