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