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