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