lib: bt_packet_create(): accept previous packet to set properties
[babeltrace.git] / plugins / text / pretty / print.c
CommitLineData
af9a82eb
JG
1/*
2 * print.c
3 *
4 * Babeltrace CTF Text Output Plugin Event Printing
5 *
6 * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
f504043c 7 * Copyright 2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
af9a82eb
JG
8 *
9 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * SOFTWARE.
28 */
29
9d408fca 30#include <babeltrace/babeltrace.h>
3d9990ac 31#include <babeltrace/bitfield-internal.h>
ad96d936 32#include <babeltrace/common-internal.h>
58a2480d 33#include <babeltrace/compat/time-internal.h>
f6ccaed9 34#include <babeltrace/assert-internal.h>
6a18b281 35#include <inttypes.h>
93a4161c 36#include <ctype.h>
3228cc1d 37#include "pretty.h"
af9a82eb 38
1556a1af
JG
39#define NSEC_PER_SEC 1000000000LL
40
5280f742 41#define COLOR_NAME BT_COMMON_COLOR_BOLD
08899d39 42#define COLOR_FIELD_NAME BT_COMMON_COLOR_FG_CYAN
5280f742
PP
43#define COLOR_RST BT_COMMON_COLOR_RESET
44#define COLOR_STRING_VALUE BT_COMMON_COLOR_BOLD
45#define COLOR_NUMBER_VALUE BT_COMMON_COLOR_BOLD
46#define COLOR_ENUM_MAPPING_NAME BT_COMMON_COLOR_BOLD
47#define COLOR_UNKNOWN BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_RED
08899d39 48#define COLOR_EVENT_NAME BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_MAGENTA
5280f742 49#define COLOR_TIMESTAMP BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_YELLOW
ad96d936 50
af9a82eb
JG
51struct timestamp {
52 int64_t real_timestamp; /* Relative to UNIX epoch. */
53 uint64_t clock_value; /* In cycles. */
54};
55
6a18b281 56static
3228cc1d 57enum bt_component_status print_field(struct pretty_component *pretty,
50842bdc 58 struct bt_field *field, bool print_names,
2b4c4a7c 59 GQuark *filters_fields, int filter_array_len);
6a18b281 60
ad96d936 61static
3228cc1d 62void print_name_equal(struct pretty_component *pretty, const char *name)
ad96d936 63{
3228cc1d 64 if (pretty->use_colors) {
5280f742
PP
65 g_string_append_printf(pretty->string, "%s%s%s = ", COLOR_NAME,
66 name, COLOR_RST);
ad96d936 67 } else {
5280f742 68 g_string_append_printf(pretty->string, "%s = ", name);
ad96d936
PP
69 }
70}
71
72static
3228cc1d 73void print_field_name_equal(struct pretty_component *pretty, const char *name)
ad96d936 74{
3228cc1d 75 if (pretty->use_colors) {
5280f742
PP
76 g_string_append_printf(pretty->string, "%s%s%s = ",
77 COLOR_FIELD_NAME, name, COLOR_RST);
ad96d936 78 } else {
5280f742 79 g_string_append_printf(pretty->string, "%s = ", name);
ad96d936
PP
80 }
81}
82
af9a82eb 83static
3228cc1d 84void print_timestamp_cycles(struct pretty_component *pretty,
50842bdc 85 struct bt_event *event)
af9a82eb 86{
1556a1af 87 int ret;
50842bdc 88 struct bt_clock_value *clock_value;
1556a1af
JG
89 uint64_t cycles;
90
e22b45d0 91 clock_value = bt_event_borrow_default_clock_value(event);
1556a1af 92 if (!clock_value) {
5280f742 93 g_string_append(pretty->string, "????????????????????");
1556a1af
JG
94 return;
95 }
96
50842bdc 97 ret = bt_clock_value_get_value(clock_value, &cycles);
1556a1af 98 if (ret) {
5280f742
PP
99 // TODO: log, this is unexpected
100 g_string_append(pretty->string, "Error");
1556a1af
JG
101 return;
102 }
5280f742
PP
103
104 g_string_append_printf(pretty->string, "%020" PRIu64, cycles);
3af83b5a 105
3228cc1d
PP
106 if (pretty->last_cycles_timestamp != -1ULL) {
107 pretty->delta_cycles = cycles - pretty->last_cycles_timestamp;
3af83b5a 108 }
3228cc1d 109 pretty->last_cycles_timestamp = cycles;
af9a82eb
JG
110}
111
112static
3228cc1d 113void print_timestamp_wall(struct pretty_component *pretty,
50842bdc 114 struct bt_clock_value *clock_value)
af9a82eb 115{
1556a1af 116 int ret;
1556a1af
JG
117 int64_t ts_nsec = 0; /* add configurable offset */
118 int64_t ts_sec = 0; /* add configurable offset */
119 uint64_t ts_sec_abs, ts_nsec_abs;
120 bool is_negative;
af9a82eb 121
1556a1af 122 if (!clock_value) {
5280f742 123 g_string_append(pretty->string, "??:??:??.?????????");
1556a1af
JG
124 return;
125 }
126
50842bdc 127 ret = bt_clock_value_get_value_ns_from_epoch(clock_value, &ts_nsec);
1556a1af 128 if (ret) {
5280f742
PP
129 // TODO: log, this is unexpected
130 g_string_append(pretty->string, "Error");
1556a1af
JG
131 return;
132 }
133
3228cc1d
PP
134 if (pretty->last_real_timestamp != -1ULL) {
135 pretty->delta_real_timestamp = ts_nsec - pretty->last_real_timestamp;
3af83b5a 136 }
3af83b5a 137
5280f742 138 pretty->last_real_timestamp = ts_nsec;
1556a1af
JG
139 ts_sec += ts_nsec / NSEC_PER_SEC;
140 ts_nsec = ts_nsec % NSEC_PER_SEC;
5280f742 141
1556a1af
JG
142 if (ts_sec >= 0 && ts_nsec >= 0) {
143 is_negative = false;
144 ts_sec_abs = ts_sec;
145 ts_nsec_abs = ts_nsec;
146 } else if (ts_sec > 0 && ts_nsec < 0) {
147 is_negative = false;
148 ts_sec_abs = ts_sec - 1;
149 ts_nsec_abs = NSEC_PER_SEC + ts_nsec;
150 } else if (ts_sec == 0 && ts_nsec < 0) {
151 is_negative = true;
152 ts_sec_abs = ts_sec;
153 ts_nsec_abs = -ts_nsec;
154 } else if (ts_sec < 0 && ts_nsec > 0) {
155 is_negative = true;
156 ts_sec_abs = -(ts_sec + 1);
157 ts_nsec_abs = NSEC_PER_SEC - ts_nsec;
158 } else if (ts_sec < 0 && ts_nsec == 0) {
159 is_negative = true;
160 ts_sec_abs = -ts_sec;
161 ts_nsec_abs = ts_nsec;
162 } else { /* (ts_sec < 0 && ts_nsec < 0) */
163 is_negative = true;
164 ts_sec_abs = -ts_sec;
165 ts_nsec_abs = -ts_nsec;
166 }
167
3228cc1d 168 if (!pretty->options.clock_seconds) {
1556a1af
JG
169 struct tm tm;
170 time_t time_s = (time_t) ts_sec_abs;
171
18adbd19 172 if (is_negative && !pretty->negative_timestamp_warning_done) {
5280f742 173 // TODO: log instead
1556a1af 174 fprintf(stderr, "[warning] Fallback to [sec.ns] to print negative time value. Use --clock-seconds.\n");
18adbd19 175 pretty->negative_timestamp_warning_done = true;
1556a1af
JG
176 goto seconds;
177 }
178
3228cc1d 179 if (!pretty->options.clock_gmt) {
1556a1af
JG
180 struct tm *res;
181
58a2480d 182 res = bt_localtime_r(&time_s, &tm);
1556a1af 183 if (!res) {
5280f742 184 // TODO: log instead
1556a1af
JG
185 fprintf(stderr, "[warning] Unable to get localtime.\n");
186 goto seconds;
187 }
188 } else {
189 struct tm *res;
190
58a2480d 191 res = bt_gmtime_r(&time_s, &tm);
1556a1af 192 if (!res) {
5280f742 193 // TODO: log instead
1556a1af
JG
194 fprintf(stderr, "[warning] Unable to get gmtime.\n");
195 goto seconds;
196 }
197 }
3228cc1d 198 if (pretty->options.clock_date) {
1556a1af
JG
199 char timestr[26];
200 size_t res;
201
202 /* Print date and time */
203 res = strftime(timestr, sizeof(timestr),
4d2a94f1 204 "%Y-%m-%d ", &tm);
1556a1af 205 if (!res) {
5280f742 206 // TODO: log instead
1556a1af
JG
207 fprintf(stderr, "[warning] Unable to print ascii time.\n");
208 goto seconds;
209 }
5280f742
PP
210
211 g_string_append(pretty->string, timestr);
1556a1af 212 }
5280f742 213
1556a1af 214 /* Print time in HH:MM:SS.ns */
5280f742
PP
215 g_string_append_printf(pretty->string,
216 "%02d:%02d:%02d.%09" PRIu64, tm.tm_hour, tm.tm_min,
217 tm.tm_sec, ts_nsec_abs);
1556a1af
JG
218 goto end;
219 }
220seconds:
5280f742
PP
221 g_string_append_printf(pretty->string, "%s%" PRId64 ".%09" PRIu64,
222 is_negative ? "-" : "", ts_sec_abs, ts_nsec_abs);
1556a1af
JG
223end:
224 return;
af9a82eb
JG
225}
226
227static
3228cc1d 228enum bt_component_status print_event_timestamp(struct pretty_component *pretty,
e22b45d0 229 struct bt_event *event, bool *start_line)
af9a82eb 230{
3228cc1d 231 bool print_names = pretty->options.print_header_field_names;
af9a82eb 232 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
50842bdc
PP
233 struct bt_stream *stream = NULL;
234 struct bt_stream_class *stream_class = NULL;
235 struct bt_trace *trace = NULL;
e22b45d0 236 struct bt_clock_value *clock_value = NULL;
af9a82eb 237
a82e90e8 238 stream = bt_event_borrow_stream(event);
af9a82eb
JG
239 if (!stream) {
240 ret = BT_COMPONENT_STATUS_ERROR;
241 goto end;
242 }
243
a82e90e8 244 stream_class = bt_stream_borrow_class(stream);
f504043c
MD
245 if (!stream_class) {
246 ret = BT_COMPONENT_STATUS_ERROR;
247 goto end;
248 }
a82e90e8 249 trace = bt_stream_class_borrow_trace(stream_class);
f504043c
MD
250 if (!trace) {
251 ret = BT_COMPONENT_STATUS_ERROR;
252 goto end;
253 }
d9f65f09 254
e22b45d0
PP
255 clock_value = bt_event_borrow_default_clock_value(event);
256 if (!clock_value) {
257 /* No default clock value: skip the timestamp without an error */
f504043c
MD
258 goto end;
259 }
af9a82eb 260
ad96d936 261 if (print_names) {
3228cc1d 262 print_name_equal(pretty, "timestamp");
ad96d936 263 } else {
5280f742 264 g_string_append(pretty->string, "[");
ad96d936 265 }
3228cc1d 266 if (pretty->use_colors) {
5280f742 267 g_string_append(pretty->string, COLOR_TIMESTAMP);
ad96d936 268 }
3228cc1d 269 if (pretty->options.print_timestamp_cycles) {
e22b45d0 270 print_timestamp_cycles(pretty, event);
af9a82eb 271 } else {
50842bdc 272 struct bt_clock_value *clock_value =
e22b45d0 273 bt_event_borrow_default_clock_value(event);
08899d39
PP
274
275 print_timestamp_wall(pretty, clock_value);
af9a82eb 276 }
3228cc1d 277 if (pretty->use_colors) {
5280f742 278 g_string_append(pretty->string, COLOR_RST);
ad96d936 279 }
af9a82eb 280
c3c30b08 281 if (!print_names)
5280f742 282 g_string_append(pretty->string, "] ");
c3c30b08 283
3228cc1d 284 if (pretty->options.print_delta_field) {
ad96d936 285 if (print_names) {
5280f742 286 g_string_append(pretty->string, ", ");
3228cc1d 287 print_name_equal(pretty, "delta");
ad96d936 288 } else {
5280f742 289 g_string_append(pretty->string, "(");
ad96d936 290 }
3228cc1d
PP
291 if (pretty->options.print_timestamp_cycles) {
292 if (pretty->delta_cycles == -1ULL) {
5280f742
PP
293 g_string_append(pretty->string,
294 "+??????????\?\?) "); /* Not a trigraph. */
3af83b5a 295 } else {
5280f742
PP
296 g_string_append_printf(pretty->string,
297 "+%012" PRIu64, pretty->delta_cycles);
3af83b5a
MD
298 }
299 } else {
3228cc1d 300 if (pretty->delta_real_timestamp != -1ULL) {
3af83b5a 301 uint64_t delta_sec, delta_nsec, delta;
f504043c 302
3228cc1d 303 delta = pretty->delta_real_timestamp;
3af83b5a
MD
304 delta_sec = delta / NSEC_PER_SEC;
305 delta_nsec = delta % NSEC_PER_SEC;
5280f742
PP
306 g_string_append_printf(pretty->string,
307 "+%" PRIu64 ".%09" PRIu64,
3af83b5a
MD
308 delta_sec, delta_nsec);
309 } else {
5280f742 310 g_string_append(pretty->string, "+?.?????????");
3af83b5a
MD
311 }
312 }
313 if (!print_names) {
5280f742 314 g_string_append(pretty->string, ") ");
3af83b5a
MD
315 }
316 }
317 *start_line = !print_names;
f504043c 318
af9a82eb 319end:
af9a82eb
JG
320 return ret;
321}
322
6a18b281 323static
3228cc1d 324enum bt_component_status print_event_header(struct pretty_component *pretty,
e22b45d0 325 struct bt_event *event)
af9a82eb 326{
3228cc1d 327 bool print_names = pretty->options.print_header_field_names;
6a18b281 328 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
50842bdc
PP
329 struct bt_event_class *event_class = NULL;
330 struct bt_stream_class *stream_class = NULL;
331 struct bt_trace *trace_class = NULL;
60535549 332 int dom_print = 0;
af9a82eb 333
a82e90e8 334 event_class = bt_event_borrow_class(event);
6a18b281
MD
335 if (!event_class) {
336 ret = BT_COMPONENT_STATUS_ERROR;
337 goto end;
338 }
a82e90e8 339 stream_class = bt_event_class_borrow_stream_class(event_class);
c3c30b08
MD
340 if (!stream_class) {
341 ret = BT_COMPONENT_STATUS_ERROR;
342 goto end;
343 }
a82e90e8 344 trace_class = bt_stream_class_borrow_trace(stream_class);
c3c30b08
MD
345 if (!trace_class) {
346 ret = BT_COMPONENT_STATUS_ERROR;
347 goto end;
348 }
e22b45d0 349 ret = print_event_timestamp(pretty, event, &pretty->start_line);
af9a82eb
JG
350 if (ret != BT_COMPONENT_STATUS_OK) {
351 goto end;
352 }
3228cc1d 353 if (pretty->options.print_trace_field) {
c3c30b08
MD
354 const char *name;
355
50842bdc 356 name = bt_trace_get_name(trace_class);
c3c30b08 357 if (name) {
3228cc1d 358 if (!pretty->start_line) {
5280f742 359 g_string_append(pretty->string, ", ");
c3c30b08 360 }
c3c30b08 361 if (print_names) {
3228cc1d 362 print_name_equal(pretty, "trace");
c3c30b08 363 }
5280f742
PP
364
365 g_string_append(pretty->string, name);
366
60535549 367 if (!print_names) {
5280f742 368 g_string_append(pretty->string, " ");
60535549 369 }
c3c30b08
MD
370 }
371 }
3228cc1d 372 if (pretty->options.print_trace_hostname_field) {
c3c30b08
MD
373 struct bt_value *hostname_str;
374
a82e90e8
PP
375 hostname_str = bt_trace_borrow_environment_field_value_by_name(
376 trace_class, "hostname");
c3c30b08
MD
377 if (hostname_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:hostname");
c3c30b08
MD
385 }
386 if (bt_value_string_get(hostname_str, &str)
387 == BT_VALUE_STATUS_OK) {
5280f742 388 g_string_append(pretty->string, str);
c3c30b08 389 }
60535549 390 dom_print = 1;
c3c30b08
MD
391 }
392 }
3228cc1d 393 if (pretty->options.print_trace_domain_field) {
c3c30b08
MD
394 struct bt_value *domain_str;
395
a82e90e8
PP
396 domain_str = bt_trace_borrow_environment_field_value_by_name(
397 trace_class, "domain");
c3c30b08
MD
398 if (domain_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:domain");
60535549 406 } else if (dom_print) {
5280f742 407 g_string_append(pretty->string, ":");
c3c30b08
MD
408 }
409 if (bt_value_string_get(domain_str, &str)
410 == BT_VALUE_STATUS_OK) {
5280f742 411 g_string_append(pretty->string, str);
c3c30b08 412 }
60535549 413 dom_print = 1;
c3c30b08
MD
414 }
415 }
3228cc1d 416 if (pretty->options.print_trace_procname_field) {
c3c30b08
MD
417 struct bt_value *procname_str;
418
a82e90e8
PP
419 procname_str = bt_trace_borrow_environment_field_value_by_name(
420 trace_class, "procname");
c3c30b08
MD
421 if (procname_str) {
422 const char *str;
423
3228cc1d 424 if (!pretty->start_line) {
5280f742 425 g_string_append(pretty->string, ", ");
c3c30b08 426 }
c3c30b08 427 if (print_names) {
3228cc1d 428 print_name_equal(pretty, "trace:procname");
60535549 429 } else if (dom_print) {
5280f742 430 g_string_append(pretty->string, ":");
c3c30b08
MD
431 }
432 if (bt_value_string_get(procname_str, &str)
433 == BT_VALUE_STATUS_OK) {
5280f742 434 g_string_append(pretty->string, str);
c3c30b08 435 }
a82e90e8 436
60535549 437 dom_print = 1;
c3c30b08
MD
438 }
439 }
3228cc1d 440 if (pretty->options.print_trace_vpid_field) {
c3c30b08
MD
441 struct bt_value *vpid_value;
442
a82e90e8
PP
443 vpid_value = bt_trace_borrow_environment_field_value_by_name(
444 trace_class, "vpid");
c3c30b08
MD
445 if (vpid_value) {
446 int64_t value;
447
3228cc1d 448 if (!pretty->start_line) {
5280f742 449 g_string_append(pretty->string, ", ");
c3c30b08 450 }
c3c30b08 451 if (print_names) {
3228cc1d 452 print_name_equal(pretty, "trace:vpid");
60535549 453 } else if (dom_print) {
5280f742 454 g_string_append(pretty->string, ":");
c3c30b08
MD
455 }
456 if (bt_value_integer_get(vpid_value, &value)
457 == BT_VALUE_STATUS_OK) {
5280f742 458 g_string_append_printf(pretty->string, "(%" PRId64 ")", value);
c3c30b08 459 }
a82e90e8 460
60535549 461 dom_print = 1;
c3c30b08
MD
462 }
463 }
3228cc1d 464 if (pretty->options.print_loglevel_field) {
cf76ce92 465 static const char *log_level_names[] = {
50842bdc
PP
466 [ BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY ] = "TRACE_EMERG",
467 [ BT_EVENT_CLASS_LOG_LEVEL_ALERT ] = "TRACE_ALERT",
468 [ BT_EVENT_CLASS_LOG_LEVEL_CRITICAL ] = "TRACE_CRIT",
469 [ BT_EVENT_CLASS_LOG_LEVEL_ERROR ] = "TRACE_ERR",
470 [ BT_EVENT_CLASS_LOG_LEVEL_WARNING ] = "TRACE_WARNING",
471 [ BT_EVENT_CLASS_LOG_LEVEL_NOTICE ] = "TRACE_NOTICE",
472 [ BT_EVENT_CLASS_LOG_LEVEL_INFO ] = "TRACE_INFO",
473 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM ] = "TRACE_DEBUG_SYSTEM",
474 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM ] = "TRACE_DEBUG_PROGRAM",
475 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS ] = "TRACE_DEBUG_PROCESS",
476 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE ] = "TRACE_DEBUG_MODULE",
477 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT ] = "TRACE_DEBUG_UNIT",
478 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION ] = "TRACE_DEBUG_FUNCTION",
479 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE ] = "TRACE_DEBUG_LINE",
480 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG ] = "TRACE_DEBUG",
cf76ce92 481 };
50842bdc 482 enum bt_event_class_log_level log_level;
cf76ce92
PP
483 const char *log_level_str = NULL;
484
50842bdc 485 log_level = bt_event_class_get_log_level(event_class);
f6ccaed9 486 BT_ASSERT(log_level != BT_EVENT_CLASS_LOG_LEVEL_UNKNOWN);
50842bdc 487 if (log_level != BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED) {
cf76ce92
PP
488 log_level_str = log_level_names[log_level];
489 }
c3c30b08 490
cf76ce92 491 if (log_level_str) {
3228cc1d 492 if (!pretty->start_line) {
5280f742 493 g_string_append(pretty->string, ", ");
c3c30b08 494 }
c3c30b08 495 if (print_names) {
3228cc1d 496 print_name_equal(pretty, "loglevel");
60535549 497 } else if (dom_print) {
5280f742 498 g_string_append(pretty->string, ":");
c3c30b08 499 }
cf76ce92
PP
500
501 g_string_append(pretty->string, log_level_str);
502 g_string_append_printf(
503 pretty->string, " (%d)", (int) log_level);
60535549 504 dom_print = 1;
c3c30b08
MD
505 }
506 }
3228cc1d 507 if (pretty->options.print_emf_field) {
cf76ce92 508 const char *uri_str;
c3c30b08 509
50842bdc 510 uri_str = bt_event_class_get_emf_uri(event_class);
c3c30b08 511 if (uri_str) {
3228cc1d 512 if (!pretty->start_line) {
5280f742 513 g_string_append(pretty->string, ", ");
c3c30b08 514 }
c3c30b08 515 if (print_names) {
3228cc1d 516 print_name_equal(pretty, "model.emf.uri");
60535549 517 } else if (dom_print) {
5280f742 518 g_string_append(pretty->string, ":");
c3c30b08 519 }
c3c30b08 520
cf76ce92 521 g_string_append(pretty->string, uri_str);
60535549 522 dom_print = 1;
c3c30b08
MD
523 }
524 }
60535549 525 if (dom_print && !print_names) {
5280f742 526 g_string_append(pretty->string, " ");
60535549 527 }
3228cc1d 528 if (!pretty->start_line) {
5280f742 529 g_string_append(pretty->string, ", ");
c3c30b08 530 }
3228cc1d 531 pretty->start_line = true;
6a18b281 532 if (print_names) {
3228cc1d 533 print_name_equal(pretty, "name");
ad96d936 534 }
3228cc1d 535 if (pretty->use_colors) {
5280f742 536 g_string_append(pretty->string, COLOR_EVENT_NAME);
6a18b281 537 }
50842bdc 538 g_string_append(pretty->string, bt_event_class_get_name(event_class));
3228cc1d 539 if (pretty->use_colors) {
5280f742 540 g_string_append(pretty->string, COLOR_RST);
ad96d936 541 }
60535549 542 if (!print_names) {
5280f742 543 g_string_append(pretty->string, ": ");
60535549 544 } else {
5280f742 545 g_string_append(pretty->string, ", ");
60535549 546 }
a82e90e8 547
af9a82eb 548end:
6a18b281
MD
549 return ret;
550}
551
552static
3228cc1d 553enum bt_component_status print_integer(struct pretty_component *pretty,
50842bdc 554 struct bt_field *field)
6a18b281
MD
555{
556 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
50842bdc
PP
557 struct bt_field_type *field_type = NULL;
558 enum bt_integer_base base;
559 enum bt_string_encoding encoding;
6a18b281 560 int signedness;
312c056a 561 struct bt_field_type *int_ft;
6a18b281
MD
562 union {
563 uint64_t u;
564 int64_t s;
565 } v;
ad96d936 566 bool rst_color = false;
312c056a 567 enum bt_field_type_id ft_id;
6a18b281 568
a82e90e8 569 field_type = bt_field_borrow_type(field);
6a18b281
MD
570 if (!field_type) {
571 ret = BT_COMPONENT_STATUS_ERROR;
572 goto end;
573 }
312c056a
PP
574
575 ft_id = bt_field_get_type_id(field);
576
577 switch (ft_id) {
578 case BT_FIELD_TYPE_ID_INTEGER:
579 int_ft = field_type;
580 break;
581 case BT_FIELD_TYPE_ID_ENUM:
582 int_ft = bt_field_type_enumeration_borrow_container_field_type(
583 field_type);
584 break;
585 default:
586 abort();
587 }
588
589 signedness = bt_field_type_integer_is_signed(int_ft);
6a18b281
MD
590 if (signedness < 0) {
591 ret = BT_COMPONENT_STATUS_ERROR;
592 goto end;
593 }
594 if (!signedness) {
312c056a 595 ret = bt_field_integer_unsigned_get_value(field, &v.u);
6a18b281 596 } else {
312c056a 597 ret = bt_field_integer_signed_get_value(field, &v.s);
6a18b281
MD
598 }
599
312c056a
PP
600 if (ret < 0) {
601 ret = BT_COMPONENT_STATUS_ERROR;
602 goto end;
603 }
604
605 encoding = bt_field_type_integer_get_encoding(int_ft);
6a18b281 606 switch (encoding) {
50842bdc
PP
607 case BT_STRING_ENCODING_UTF8:
608 case BT_STRING_ENCODING_ASCII:
5280f742 609 g_string_append_c(pretty->tmp_string, (int) v.u);
6a18b281 610 goto end;
50842bdc
PP
611 case BT_STRING_ENCODING_NONE:
612 case BT_STRING_ENCODING_UNKNOWN:
6a18b281
MD
613 break;
614 default:
615 ret = BT_COMPONENT_STATUS_ERROR;
616 goto end;
617 }
618
3228cc1d 619 if (pretty->use_colors) {
5280f742 620 g_string_append(pretty->string, COLOR_NUMBER_VALUE);
ad96d936
PP
621 rst_color = true;
622 }
623
312c056a 624 base = bt_field_type_integer_get_base(int_ft);
6a18b281 625 switch (base) {
50842bdc 626 case BT_INTEGER_BASE_BINARY:
6a18b281
MD
627 {
628 int bitnr, len;
629
312c056a 630 len = bt_field_type_integer_get_size(int_ft);
6a18b281
MD
631 if (len < 0) {
632 ret = BT_COMPONENT_STATUS_ERROR;
633 goto end;
634 }
5280f742 635 g_string_append(pretty->string, "0b");
6a18b281
MD
636 v.u = _bt_piecewise_lshift(v.u, 64 - len);
637 for (bitnr = 0; bitnr < len; bitnr++) {
5280f742 638 g_string_append_printf(pretty->string, "%u", (v.u & (1ULL << 63)) ? 1 : 0);
6a18b281
MD
639 v.u = _bt_piecewise_lshift(v.u, 1);
640 }
641 break;
642 }
50842bdc 643 case BT_INTEGER_BASE_OCTAL:
6a18b281
MD
644 {
645 if (signedness) {
646 int len;
647
312c056a 648 len = bt_field_type_integer_get_size(int_ft);
6a18b281
MD
649 if (len < 0) {
650 ret = BT_COMPONENT_STATUS_ERROR;
651 goto end;
652 }
653 if (len < 64) {
654 size_t rounded_len;
655
f6ccaed9 656 BT_ASSERT(len != 0);
6a18b281
MD
657 /* Round length to the nearest 3-bit */
658 rounded_len = (((len - 1) / 3) + 1) * 3;
659 v.u &= ((uint64_t) 1 << rounded_len) - 1;
660 }
661 }
662
5280f742 663 g_string_append_printf(pretty->string, "0%" PRIo64, v.u);
6a18b281
MD
664 break;
665 }
50842bdc
PP
666 case BT_INTEGER_BASE_DECIMAL:
667 case BT_INTEGER_BASE_UNSPECIFIED:
6a18b281 668 if (!signedness) {
5280f742 669 g_string_append_printf(pretty->string, "%" PRIu64, v.u);
6a18b281 670 } else {
5280f742 671 g_string_append_printf(pretty->string, "%" PRId64, v.s);
6a18b281
MD
672 }
673 break;
50842bdc 674 case BT_INTEGER_BASE_HEXADECIMAL:
6a18b281
MD
675 {
676 int len;
677
312c056a 678 len = bt_field_type_integer_get_size(int_ft);
6a18b281
MD
679 if (len < 0) {
680 ret = BT_COMPONENT_STATUS_ERROR;
681 goto end;
682 }
683 if (len < 64) {
684 /* Round length to the nearest nibble */
685 uint8_t rounded_len = ((len + 3) & ~0x3);
686
687 v.u &= ((uint64_t) 1 << rounded_len) - 1;
688 }
689
5280f742 690 g_string_append_printf(pretty->string, "0x%" PRIX64, v.u);
6a18b281
MD
691 break;
692 }
693 default:
694 ret = BT_COMPONENT_STATUS_ERROR;
695 goto end;
696 }
697end:
ad96d936 698 if (rst_color) {
5280f742 699 g_string_append(pretty->string, COLOR_RST);
ad96d936 700 }
6a18b281
MD
701 return ret;
702}
703
93a4161c 704static
3228cc1d 705void print_escape_string(struct pretty_component *pretty, const char *str)
93a4161c
JD
706{
707 int i;
708
5280f742
PP
709 g_string_append_c(pretty->string, '"');
710
93a4161c
JD
711 for (i = 0; i < strlen(str); i++) {
712 /* Escape sequences not recognized by iscntrl(). */
713 switch (str[i]) {
714 case '\\':
5280f742 715 g_string_append(pretty->string, "\\\\");
93a4161c
JD
716 continue;
717 case '\'':
5280f742 718 g_string_append(pretty->string, "\\\'");
93a4161c
JD
719 continue;
720 case '\"':
5280f742 721 g_string_append(pretty->string, "\\\"");
93a4161c
JD
722 continue;
723 case '\?':
5280f742 724 g_string_append(pretty->string, "\\\?");
93a4161c
JD
725 continue;
726 }
727
728 /* Standard characters. */
729 if (!iscntrl(str[i])) {
5280f742 730 g_string_append_c(pretty->string, str[i]);
93a4161c
JD
731 continue;
732 }
733
734 switch (str[i]) {
735 case '\0':
5280f742 736 g_string_append(pretty->string, "\\0");
93a4161c
JD
737 break;
738 case '\a':
5280f742 739 g_string_append(pretty->string, "\\a");
93a4161c
JD
740 break;
741 case '\b':
5280f742 742 g_string_append(pretty->string, "\\b");
93a4161c
JD
743 break;
744 case '\e':
5280f742 745 g_string_append(pretty->string, "\\e");
93a4161c
JD
746 break;
747 case '\f':
5280f742 748 g_string_append(pretty->string, "\\f");
93a4161c
JD
749 break;
750 case '\n':
5280f742 751 g_string_append(pretty->string, "\\n");
93a4161c
JD
752 break;
753 case '\r':
5280f742 754 g_string_append(pretty->string, "\\r");
93a4161c
JD
755 break;
756 case '\t':
5280f742 757 g_string_append(pretty->string, "\\t");
93a4161c
JD
758 break;
759 case '\v':
5280f742 760 g_string_append(pretty->string, "\\v");
93a4161c
JD
761 break;
762 default:
763 /* Unhandled control-sequence, print as hex. */
5280f742 764 g_string_append_printf(pretty->string, "\\x%02x", str[i]);
93a4161c
JD
765 break;
766 }
767 }
5280f742
PP
768
769 g_string_append_c(pretty->string, '"');
93a4161c
JD
770}
771
6a18b281 772static
3228cc1d 773enum bt_component_status print_enum(struct pretty_component *pretty,
50842bdc 774 struct bt_field *field)
6a18b281
MD
775{
776 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
50842bdc
PP
777 struct bt_field_type *enumeration_field_type = NULL;
778 struct bt_field_type *container_field_type = NULL;
779 struct bt_field_type_enumeration_mapping_iterator *iter = NULL;
96e8f959 780 int nr_mappings = 0;
96e8f959 781
a82e90e8 782 enumeration_field_type = bt_field_borrow_type(field);
96e8f959
MD
783 if (!enumeration_field_type) {
784 ret = BT_COMPONENT_STATUS_ERROR;
785 goto end;
786 }
312c056a
PP
787 container_field_type =
788 bt_field_type_enumeration_borrow_container_field_type(
789 enumeration_field_type);
96e8f959
MD
790 if (!container_field_type) {
791 ret = BT_COMPONENT_STATUS_ERROR;
792 goto end;
793 }
312c056a
PP
794 iter = bt_field_enumeration_get_mappings(field);
795 if (!iter) {
96e8f959
MD
796 ret = BT_COMPONENT_STATUS_ERROR;
797 goto end;
798 }
83ef3205 799 g_string_append(pretty->string, "( ");
50842bdc 800 ret = bt_field_type_enumeration_mapping_iterator_next(iter);
74fb0452 801 if (ret) {
83ef3205
MD
802 if (pretty->use_colors) {
803 g_string_append(pretty->string, COLOR_UNKNOWN);
804 }
805 g_string_append(pretty->string, "<unknown>");
806 if (pretty->use_colors) {
807 g_string_append(pretty->string, COLOR_RST);
808 }
809 goto skip_loop;
96e8f959 810 }
96e8f959
MD
811 for (;;) {
812 const char *mapping_name;
813
3dca2276 814 if (bt_field_type_enumeration_mapping_iterator_signed_get(
96e8f959
MD
815 iter, &mapping_name, NULL, NULL) < 0) {
816 ret = BT_COMPONENT_STATUS_ERROR;
817 goto end;
818 }
819 if (nr_mappings++)
5280f742 820 g_string_append(pretty->string, ", ");
3228cc1d 821 if (pretty->use_colors) {
5280f742 822 g_string_append(pretty->string, COLOR_ENUM_MAPPING_NAME);
ad96d936 823 }
3228cc1d
PP
824 print_escape_string(pretty, mapping_name);
825 if (pretty->use_colors) {
5280f742 826 g_string_append(pretty->string, COLOR_RST);
ad96d936 827 }
50842bdc 828 if (bt_field_type_enumeration_mapping_iterator_next(iter) < 0) {
96e8f959
MD
829 break;
830 }
831 }
83ef3205 832skip_loop:
5280f742 833 g_string_append(pretty->string, " : container = ");
312c056a 834 ret = print_integer(pretty, field);
6a18b281
MD
835 if (ret != BT_COMPONENT_STATUS_OK) {
836 goto end;
837 }
5280f742 838 g_string_append(pretty->string, " )");
6a18b281 839end:
96e8f959 840 bt_put(iter);
6a18b281
MD
841 return ret;
842}
843
2b4c4a7c 844static
3228cc1d 845int filter_field_name(struct pretty_component *pretty, const char *field_name,
2b4c4a7c
JD
846 GQuark *filter_fields, int filter_array_len)
847{
848 int i;
849 GQuark field_quark = g_quark_try_string(field_name);
850
3228cc1d 851 if (!field_quark || pretty->options.verbose) {
2b4c4a7c
JD
852 return 1;
853 }
854
855 for (i = 0; i < filter_array_len; i++) {
856 if (field_quark == filter_fields[i]) {
857 return 0;
858 }
859 }
860 return 1;
861}
862
6a18b281 863static
3228cc1d 864enum bt_component_status print_struct_field(struct pretty_component *pretty,
50842bdc
PP
865 struct bt_field *_struct,
866 struct bt_field_type *struct_type,
2b4c4a7c
JD
867 int i, bool print_names, int *nr_printed_fields,
868 GQuark *filter_fields, int filter_array_len)
6a18b281
MD
869{
870 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
871 const char *field_name;
50842bdc
PP
872 struct bt_field *field = NULL;
873 struct bt_field_type *field_type = NULL;;
6a18b281 874
a82e90e8 875 field = bt_field_structure_borrow_field_by_index(_struct, i);
6a18b281
MD
876 if (!field) {
877 ret = BT_COMPONENT_STATUS_ERROR;
878 goto end;
879 }
a82e90e8 880 if (bt_field_type_structure_borrow_field_by_index(struct_type,
6a18b281
MD
881 &field_name, &field_type, i) < 0) {
882 ret = BT_COMPONENT_STATUS_ERROR;
883 goto end;
884 }
885
3228cc1d 886 if (filter_fields && !filter_field_name(pretty, field_name,
2b4c4a7c
JD
887 filter_fields, filter_array_len)) {
888 ret = BT_COMPONENT_STATUS_OK;
889 goto end;
890 }
891
892 if (*nr_printed_fields > 0) {
5280f742 893 g_string_append(pretty->string, ", ");
6a18b281 894 } else {
5280f742 895 g_string_append(pretty->string, " ");
6a18b281
MD
896 }
897 if (print_names) {
6acddae3 898 print_field_name_equal(pretty, field_name);
6a18b281 899 }
3228cc1d 900 ret = print_field(pretty, field, print_names, NULL, 0);
2b4c4a7c 901 *nr_printed_fields += 1;
a82e90e8 902
6a18b281 903end:
6a18b281
MD
904 return ret;
905}
906
907static
3228cc1d 908enum bt_component_status print_struct(struct pretty_component *pretty,
50842bdc 909 struct bt_field *_struct, bool print_names,
2b4c4a7c 910 GQuark *filter_fields, int filter_array_len)
6a18b281
MD
911{
912 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
50842bdc 913 struct bt_field_type *struct_type = NULL;
2b4c4a7c 914 int nr_fields, i, nr_printed_fields;
6a18b281 915
a82e90e8 916 struct_type = bt_field_borrow_type(_struct);
6a18b281
MD
917 if (!struct_type) {
918 ret = BT_COMPONENT_STATUS_ERROR;
919 goto end;
920 }
50842bdc 921 nr_fields = bt_field_type_structure_get_field_count(struct_type);
6a18b281
MD
922 if (nr_fields < 0) {
923 ret = BT_COMPONENT_STATUS_ERROR;
924 goto end;
925 }
5280f742 926 g_string_append(pretty->string, "{");
3228cc1d 927 pretty->depth++;
2b4c4a7c 928 nr_printed_fields = 0;
6a18b281 929 for (i = 0; i < nr_fields; i++) {
3228cc1d 930 ret = print_struct_field(pretty, _struct, struct_type, i,
2b4c4a7c
JD
931 print_names, &nr_printed_fields, filter_fields,
932 filter_array_len);
6a18b281
MD
933 if (ret != BT_COMPONENT_STATUS_OK) {
934 goto end;
935 }
936 }
3228cc1d 937 pretty->depth--;
5280f742 938 g_string_append(pretty->string, " }");
a82e90e8 939
6a18b281 940end:
6a18b281
MD
941 return ret;
942}
943
944static
3228cc1d 945enum bt_component_status print_array_field(struct pretty_component *pretty,
50842bdc 946 struct bt_field *array, uint64_t i,
6a18b281
MD
947 bool is_string, bool print_names)
948{
949 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
50842bdc 950 struct bt_field *field = NULL;
6a18b281
MD
951
952 if (!is_string) {
953 if (i != 0) {
5280f742 954 g_string_append(pretty->string, ", ");
6a18b281 955 } else {
5280f742 956 g_string_append(pretty->string, " ");
6a18b281 957 }
60535549 958 if (print_names) {
5280f742 959 g_string_append_printf(pretty->string, "[%" PRIu64 "] = ", i);
60535549 960 }
6a18b281 961 }
a82e90e8 962 field = bt_field_array_borrow_field(array, i);
6a18b281
MD
963 if (!field) {
964 ret = BT_COMPONENT_STATUS_ERROR;
965 goto end;
966 }
3228cc1d 967 ret = print_field(pretty, field, print_names, NULL, 0);
a82e90e8 968
6a18b281 969end:
6a18b281
MD
970 return ret;
971}
972
973static
3228cc1d 974enum bt_component_status print_array(struct pretty_component *pretty,
50842bdc 975 struct bt_field *array, bool print_names)
6a18b281
MD
976{
977 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
50842bdc
PP
978 struct bt_field_type *array_type = NULL, *field_type = NULL;
979 enum bt_field_type_id type_id;
6a18b281
MD
980 int64_t len;
981 uint64_t i;
982 bool is_string = false;
983
a82e90e8 984 array_type = bt_field_borrow_type(array);
6a18b281
MD
985 if (!array_type) {
986 ret = BT_COMPONENT_STATUS_ERROR;
987 goto end;
988 }
a82e90e8 989 field_type = bt_field_type_array_borrow_element_field_type(array_type);
6a18b281
MD
990 if (!field_type) {
991 ret = BT_COMPONENT_STATUS_ERROR;
992 goto end;
993 }
50842bdc 994 len = bt_field_type_array_get_length(array_type);
6a18b281
MD
995 if (len < 0) {
996 ret = BT_COMPONENT_STATUS_ERROR;
997 goto end;
998 }
50842bdc
PP
999 type_id = bt_field_type_get_type_id(field_type);
1000 if (type_id == BT_FIELD_TYPE_ID_INTEGER) {
1001 enum bt_string_encoding encoding;
6a18b281 1002
50842bdc
PP
1003 encoding = bt_field_type_integer_get_encoding(field_type);
1004 if (encoding == BT_STRING_ENCODING_UTF8
1005 || encoding == BT_STRING_ENCODING_ASCII) {
6a18b281
MD
1006 int integer_len, integer_alignment;
1007
50842bdc 1008 integer_len = bt_field_type_integer_get_size(field_type);
6a18b281
MD
1009 if (integer_len < 0) {
1010 return BT_COMPONENT_STATUS_ERROR;
1011 }
50842bdc 1012 integer_alignment = bt_field_type_get_alignment(field_type);
6a18b281
MD
1013 if (integer_alignment < 0) {
1014 return BT_COMPONENT_STATUS_ERROR;
1015 }
1016 if (integer_len == CHAR_BIT
1017 && integer_alignment == CHAR_BIT) {
1018 is_string = true;
1019 }
1020 }
1021 }
1022
1023 if (is_string) {
5280f742 1024 g_string_assign(pretty->tmp_string, "");
6a18b281 1025 } else {
5280f742 1026 g_string_append(pretty->string, "[");
6a18b281
MD
1027 }
1028
3228cc1d 1029 pretty->depth++;
6a18b281 1030 for (i = 0; i < len; i++) {
3228cc1d 1031 ret = print_array_field(pretty, array, i, is_string, print_names);
6a18b281
MD
1032 if (ret != BT_COMPONENT_STATUS_OK) {
1033 goto end;
1034 }
1035 }
3228cc1d 1036 pretty->depth--;
6a18b281
MD
1037
1038 if (is_string) {
3228cc1d 1039 if (pretty->use_colors) {
5280f742 1040 g_string_append(pretty->string, COLOR_STRING_VALUE);
ad96d936 1041 }
5280f742 1042 print_escape_string(pretty, pretty->tmp_string->str);
3228cc1d 1043 if (pretty->use_colors) {
5280f742 1044 g_string_append(pretty->string, COLOR_RST);
ad96d936 1045 }
6a18b281 1046 } else {
5280f742 1047 g_string_append(pretty->string, " ]");
6a18b281 1048 }
a82e90e8 1049
6a18b281 1050end:
6a18b281
MD
1051 return ret;
1052}
1053
1054static
3228cc1d 1055enum bt_component_status print_sequence_field(struct pretty_component *pretty,
50842bdc 1056 struct bt_field *seq, uint64_t i,
6a18b281
MD
1057 bool is_string, bool print_names)
1058{
1059 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
50842bdc 1060 struct bt_field *field = NULL;
6a18b281
MD
1061
1062 if (!is_string) {
1063 if (i != 0) {
5280f742 1064 g_string_append(pretty->string, ", ");
6a18b281 1065 } else {
5280f742 1066 g_string_append(pretty->string, " ");
6a18b281 1067 }
60535549 1068 if (print_names) {
5280f742 1069 g_string_append_printf(pretty->string, "[%" PRIu64 "] = ", i);
60535549 1070 }
6a18b281 1071 }
a82e90e8 1072 field = bt_field_sequence_borrow_field(seq, i);
6a18b281
MD
1073 if (!field) {
1074 ret = BT_COMPONENT_STATUS_ERROR;
1075 goto end;
1076 }
3228cc1d 1077 ret = print_field(pretty, field, print_names, NULL, 0);
a82e90e8 1078
6a18b281 1079end:
6a18b281
MD
1080 return ret;
1081}
1082
1083static
3228cc1d 1084enum bt_component_status print_sequence(struct pretty_component *pretty,
50842bdc 1085 struct bt_field *seq, bool print_names)
6a18b281
MD
1086{
1087 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
50842bdc 1088 struct bt_field_type *seq_type = NULL, *field_type = NULL;
50842bdc 1089 enum bt_field_type_id type_id;
312c056a 1090 int64_t len;
6a18b281
MD
1091 uint64_t i;
1092 bool is_string = false;
1093
a82e90e8 1094 seq_type = bt_field_borrow_type(seq);
6a18b281
MD
1095 if (!seq_type) {
1096 ret = BT_COMPONENT_STATUS_ERROR;
1097 goto end;
1098 }
312c056a
PP
1099 len = bt_field_sequence_get_length(seq);
1100 if (len < 0) {
6a18b281
MD
1101 ret = BT_COMPONENT_STATUS_ERROR;
1102 goto end;
1103 }
a82e90e8 1104 field_type = bt_field_type_sequence_borrow_element_field_type(seq_type);
6a18b281
MD
1105 if (!field_type) {
1106 ret = BT_COMPONENT_STATUS_ERROR;
1107 goto end;
1108 }
50842bdc
PP
1109 type_id = bt_field_type_get_type_id(field_type);
1110 if (type_id == BT_FIELD_TYPE_ID_INTEGER) {
1111 enum bt_string_encoding encoding;
6a18b281 1112
50842bdc
PP
1113 encoding = bt_field_type_integer_get_encoding(field_type);
1114 if (encoding == BT_STRING_ENCODING_UTF8
1115 || encoding == BT_STRING_ENCODING_ASCII) {
6a18b281
MD
1116 int integer_len, integer_alignment;
1117
50842bdc 1118 integer_len = bt_field_type_integer_get_size(field_type);
6a18b281
MD
1119 if (integer_len < 0) {
1120 ret = BT_COMPONENT_STATUS_ERROR;
1121 goto end;
1122 }
50842bdc 1123 integer_alignment = bt_field_type_get_alignment(field_type);
6a18b281
MD
1124 if (integer_alignment < 0) {
1125 ret = BT_COMPONENT_STATUS_ERROR;
1126 goto end;
1127 }
1128 if (integer_len == CHAR_BIT
1129 && integer_alignment == CHAR_BIT) {
1130 is_string = true;
1131 }
1132 }
1133 }
1134
1135 if (is_string) {
5280f742 1136 g_string_assign(pretty->tmp_string, "");
6a18b281 1137 } else {
5280f742 1138 g_string_append(pretty->string, "[");
6a18b281
MD
1139 }
1140
3228cc1d 1141 pretty->depth++;
6a18b281 1142 for (i = 0; i < len; i++) {
3228cc1d 1143 ret = print_sequence_field(pretty, seq, i,
6a18b281
MD
1144 is_string, print_names);
1145 if (ret != BT_COMPONENT_STATUS_OK) {
1146 goto end;
1147 }
1148 }
3228cc1d 1149 pretty->depth--;
6a18b281
MD
1150
1151 if (is_string) {
3228cc1d 1152 if (pretty->use_colors) {
5280f742 1153 g_string_append(pretty->string, COLOR_STRING_VALUE);
ad96d936 1154 }
5280f742 1155 print_escape_string(pretty, pretty->tmp_string->str);
3228cc1d 1156 if (pretty->use_colors) {
5280f742 1157 g_string_append(pretty->string, COLOR_RST);
ad96d936 1158 }
6a18b281 1159 } else {
5280f742 1160 g_string_append(pretty->string, " ]");
6a18b281 1161 }
a82e90e8 1162
6a18b281 1163end:
6a18b281
MD
1164 return ret;
1165}
1166
1167static
3228cc1d 1168enum bt_component_status print_variant(struct pretty_component *pretty,
50842bdc 1169 struct bt_field *variant, bool print_names)
6a18b281
MD
1170{
1171 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
50842bdc 1172 struct bt_field *field = NULL;
6a18b281 1173
a82e90e8 1174 field = bt_field_variant_borrow_current_field(variant);
6a18b281
MD
1175 if (!field) {
1176 ret = BT_COMPONENT_STATUS_ERROR;
1177 goto end;
1178 }
5280f742 1179 g_string_append(pretty->string, "{ ");
3228cc1d 1180 pretty->depth++;
6a18b281 1181 if (print_names) {
312c056a
PP
1182 int iret;
1183 struct bt_field_type *var_ft;
1184 struct bt_field_type *tag_ft;
1185 struct bt_field_type *container_ft;
6a18b281 1186 const char *tag_choice;
312c056a 1187 bt_bool is_signed;
50842bdc 1188 struct bt_field_type_enumeration_mapping_iterator *iter;
6a18b281 1189
312c056a
PP
1190 var_ft = bt_field_borrow_type(variant);
1191 tag_ft = bt_field_type_variant_borrow_tag_field_type(
1192 var_ft);
1193 container_ft =
1194 bt_field_type_enumeration_borrow_container_field_type(
1195 tag_ft);
1196 is_signed = bt_field_type_integer_is_signed(container_ft);
1197
1198 if (is_signed) {
1199 int64_t tag;
1200
1201 iret = bt_field_variant_get_tag_signed(variant, &tag);
1202 if (iret) {
1203 ret = BT_COMPONENT_STATUS_ERROR;
1204 goto end;
1205 }
1206
1207 iter = bt_field_type_enumeration_signed_find_mappings_by_value(
1208 tag_ft, tag);
1209 } else {
1210 uint64_t tag;
1211
1212 iret = bt_field_variant_get_tag_unsigned(variant, &tag);
1213 if (iret) {
1214 ret = BT_COMPONENT_STATUS_ERROR;
1215 goto end;
1216 }
1217
1218 iter = bt_field_type_enumeration_unsigned_find_mappings_by_value(
1219 tag_ft, tag);
1220 }
1221
1222 if (!iter) {
6a18b281
MD
1223 ret = BT_COMPONENT_STATUS_ERROR;
1224 goto end;
1225 }
e0f15669 1226
312c056a 1227 iret = bt_field_type_enumeration_mapping_iterator_next(
74fb0452
JG
1228 iter);
1229 if (!iter || ret) {
e0f15669
JG
1230 ret = BT_COMPONENT_STATUS_ERROR;
1231 goto end;
1232 }
1233
312c056a 1234 iret =
3dca2276 1235 bt_field_type_enumeration_mapping_iterator_signed_get(
8803be2a 1236 iter, &tag_choice, NULL, NULL);
312c056a 1237 if (iret) {
e0f15669 1238 bt_put(iter);
6a18b281
MD
1239 ret = BT_COMPONENT_STATUS_ERROR;
1240 goto end;
1241 }
6acddae3 1242 print_field_name_equal(pretty, tag_choice);
e0f15669 1243 bt_put(iter);
6a18b281 1244 }
3228cc1d 1245 ret = print_field(pretty, field, print_names, NULL, 0);
6a18b281
MD
1246 if (ret != BT_COMPONENT_STATUS_OK) {
1247 goto end;
1248 }
3228cc1d 1249 pretty->depth--;
5280f742 1250 g_string_append(pretty->string, " }");
a82e90e8 1251
6a18b281 1252end:
6a18b281
MD
1253 return ret;
1254}
1255
1256static
3228cc1d 1257enum bt_component_status print_field(struct pretty_component *pretty,
50842bdc 1258 struct bt_field *field, bool print_names,
2b4c4a7c 1259 GQuark *filter_fields, int filter_array_len)
6a18b281 1260{
50842bdc 1261 enum bt_field_type_id type_id;
6a18b281 1262
50842bdc 1263 type_id = bt_field_get_type_id(field);
6a18b281 1264 switch (type_id) {
3dca2276 1265 case BT_CTF_FIELD_TYPE_ID_INTEGER:
3228cc1d 1266 return print_integer(pretty, field);
3dca2276 1267 case BT_CTF_FIELD_TYPE_ID_FLOAT:
6a18b281
MD
1268 {
1269 double v;
1270
50842bdc 1271 if (bt_field_floating_point_get_value(field, &v)) {
6a18b281
MD
1272 return BT_COMPONENT_STATUS_ERROR;
1273 }
3228cc1d 1274 if (pretty->use_colors) {
5280f742 1275 g_string_append(pretty->string, COLOR_NUMBER_VALUE);
ad96d936 1276 }
5280f742 1277 g_string_append_printf(pretty->string, "%g", v);
3228cc1d 1278 if (pretty->use_colors) {
5280f742 1279 g_string_append(pretty->string, COLOR_RST);
ad96d936 1280 }
6a18b281
MD
1281 return BT_COMPONENT_STATUS_OK;
1282 }
3dca2276 1283 case BT_CTF_FIELD_TYPE_ID_ENUM:
3228cc1d 1284 return print_enum(pretty, field);
3dca2276 1285 case BT_CTF_FIELD_TYPE_ID_STRING:
95a518bf
JG
1286 {
1287 const char *str;
1288
50842bdc 1289 str = bt_field_string_get_value(field);
95a518bf
JG
1290 if (!str) {
1291 return BT_COMPONENT_STATUS_ERROR;
1292 }
1293
3228cc1d 1294 if (pretty->use_colors) {
5280f742 1295 g_string_append(pretty->string, COLOR_STRING_VALUE);
ad96d936 1296 }
95a518bf 1297 print_escape_string(pretty, str);
3228cc1d 1298 if (pretty->use_colors) {
5280f742 1299 g_string_append(pretty->string, COLOR_RST);
ad96d936 1300 }
6a18b281 1301 return BT_COMPONENT_STATUS_OK;
95a518bf 1302 }
3dca2276 1303 case BT_CTF_FIELD_TYPE_ID_STRUCT:
3228cc1d 1304 return print_struct(pretty, field, print_names, filter_fields,
2b4c4a7c 1305 filter_array_len);
3dca2276 1306 case BT_CTF_FIELD_TYPE_ID_VARIANT:
3228cc1d 1307 return print_variant(pretty, field, print_names);
3dca2276 1308 case BT_CTF_FIELD_TYPE_ID_ARRAY:
3228cc1d 1309 return print_array(pretty, field, print_names);
3dca2276 1310 case BT_CTF_FIELD_TYPE_ID_SEQUENCE:
3228cc1d 1311 return print_sequence(pretty, field, print_names);
6a18b281 1312 default:
5280f742 1313 // TODO: log instead
3228cc1d 1314 fprintf(pretty->err, "[error] Unknown type id: %d\n", (int) type_id);
6a18b281
MD
1315 return BT_COMPONENT_STATUS_ERROR;
1316 }
1317}
1318
1319static
3228cc1d 1320enum bt_component_status print_stream_packet_context(struct pretty_component *pretty,
50842bdc 1321 struct bt_event *event)
6a18b281
MD
1322{
1323 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
50842bdc
PP
1324 struct bt_packet *packet = NULL;
1325 struct bt_field *main_field = NULL;
6a18b281 1326
a82e90e8 1327 packet = bt_event_borrow_packet(event);
6a18b281
MD
1328 if (!packet) {
1329 ret = BT_COMPONENT_STATUS_ERROR;
1330 goto end;
1331 }
a82e90e8 1332 main_field = bt_packet_borrow_context(packet);
6a18b281 1333 if (!main_field) {
6a18b281
MD
1334 goto end;
1335 }
3228cc1d 1336 if (!pretty->start_line) {
5280f742 1337 g_string_append(pretty->string, ", ");
6e1bc0df 1338 }
3228cc1d
PP
1339 pretty->start_line = false;
1340 if (pretty->options.print_scope_field_names) {
1341 print_name_equal(pretty, "stream.packet.context");
6a18b281 1342 }
3228cc1d
PP
1343 ret = print_field(pretty, main_field,
1344 pretty->options.print_context_field_names,
2b4c4a7c
JD
1345 stream_packet_context_quarks,
1346 STREAM_PACKET_CONTEXT_QUARKS_LEN);
a82e90e8 1347
6a18b281 1348end:
6a18b281
MD
1349 return ret;
1350}
1351
1352static
3228cc1d 1353enum bt_component_status print_event_header_raw(struct pretty_component *pretty,
50842bdc 1354 struct bt_event *event)
6a18b281
MD
1355{
1356 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
50842bdc 1357 struct bt_field *main_field = NULL;
6a18b281 1358
a82e90e8 1359 main_field = bt_event_borrow_header(event);
6a18b281 1360 if (!main_field) {
6a18b281
MD
1361 goto end;
1362 }
3228cc1d 1363 if (!pretty->start_line) {
5280f742 1364 g_string_append(pretty->string, ", ");
6e1bc0df 1365 }
3228cc1d
PP
1366 pretty->start_line = false;
1367 if (pretty->options.print_scope_field_names) {
1368 print_name_equal(pretty, "stream.event.header");
6a18b281 1369 }
3228cc1d
PP
1370 ret = print_field(pretty, main_field,
1371 pretty->options.print_header_field_names, NULL, 0);
a82e90e8 1372
6a18b281 1373end:
6a18b281
MD
1374 return ret;
1375}
1376
1377static
3228cc1d 1378enum bt_component_status print_stream_event_context(struct pretty_component *pretty,
50842bdc 1379 struct bt_event *event)
6a18b281
MD
1380{
1381 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
50842bdc 1382 struct bt_field *main_field = NULL;
6a18b281 1383
a82e90e8 1384 main_field = bt_event_borrow_stream_event_context(event);
6a18b281 1385 if (!main_field) {
6a18b281
MD
1386 goto end;
1387 }
3228cc1d 1388 if (!pretty->start_line) {
5280f742 1389 g_string_append(pretty->string, ", ");
6e1bc0df 1390 }
3228cc1d
PP
1391 pretty->start_line = false;
1392 if (pretty->options.print_scope_field_names) {
1393 print_name_equal(pretty, "stream.event.context");
6a18b281 1394 }
3228cc1d
PP
1395 ret = print_field(pretty, main_field,
1396 pretty->options.print_context_field_names, NULL, 0);
a82e90e8 1397
6a18b281 1398end:
6a18b281
MD
1399 return ret;
1400}
1401
1402static
3228cc1d 1403enum bt_component_status print_event_context(struct pretty_component *pretty,
50842bdc 1404 struct bt_event *event)
6a18b281
MD
1405{
1406 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
50842bdc 1407 struct bt_field *main_field = NULL;
6a18b281 1408
a82e90e8 1409 main_field = bt_event_borrow_context(event);
6a18b281 1410 if (!main_field) {
6a18b281
MD
1411 goto end;
1412 }
3228cc1d 1413 if (!pretty->start_line) {
5280f742 1414 g_string_append(pretty->string, ", ");
6e1bc0df 1415 }
3228cc1d
PP
1416 pretty->start_line = false;
1417 if (pretty->options.print_scope_field_names) {
1418 print_name_equal(pretty, "event.context");
6a18b281 1419 }
3228cc1d
PP
1420 ret = print_field(pretty, main_field,
1421 pretty->options.print_context_field_names, NULL, 0);
a82e90e8 1422
6a18b281 1423end:
6a18b281
MD
1424 return ret;
1425}
1426
1427static
3228cc1d 1428enum bt_component_status print_event_payload(struct pretty_component *pretty,
50842bdc 1429 struct bt_event *event)
6a18b281
MD
1430{
1431 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
50842bdc 1432 struct bt_field *main_field = NULL;
6a18b281 1433
a82e90e8 1434 main_field = bt_event_borrow_payload(event);
6a18b281 1435 if (!main_field) {
6a18b281
MD
1436 goto end;
1437 }
3228cc1d 1438 if (!pretty->start_line) {
5280f742 1439 g_string_append(pretty->string, ", ");
6e1bc0df 1440 }
3228cc1d
PP
1441 pretty->start_line = false;
1442 if (pretty->options.print_scope_field_names) {
1443 print_name_equal(pretty, "event.fields");
6a18b281 1444 }
3228cc1d
PP
1445 ret = print_field(pretty, main_field,
1446 pretty->options.print_payload_field_names, NULL, 0);
a82e90e8 1447
6a18b281 1448end:
af9a82eb
JG
1449 return ret;
1450}
1451
08899d39
PP
1452static
1453int flush_buf(struct pretty_component *pretty)
1454{
1455 int ret = 0;
1456
1457 if (pretty->string->len == 0) {
1458 goto end;
1459 }
1460
1461 if (fwrite(pretty->string->str, pretty->string->len, 1, pretty->out) != 1) {
1462 ret = -1;
1463 }
1464
1465end:
1466 return ret;
1467}
1468
af9a82eb 1469BT_HIDDEN
3228cc1d 1470enum bt_component_status pretty_print_event(struct pretty_component *pretty,
d9f65f09 1471 struct bt_notification *event_notif)
af9a82eb
JG
1472{
1473 enum bt_component_status ret;
50842bdc 1474 struct bt_event *event =
a82e90e8 1475 bt_notification_event_borrow_event(event_notif);
af9a82eb 1476
f6ccaed9 1477 BT_ASSERT(event);
3228cc1d 1478 pretty->start_line = true;
5280f742 1479 g_string_assign(pretty->string, "");
e22b45d0 1480 ret = print_event_header(pretty, event);
af9a82eb
JG
1481 if (ret != BT_COMPONENT_STATUS_OK) {
1482 goto end;
1483 }
6a18b281 1484
3228cc1d 1485 ret = print_stream_packet_context(pretty, event);
6a18b281
MD
1486 if (ret != BT_COMPONENT_STATUS_OK) {
1487 goto end;
1488 }
6a18b281 1489
3228cc1d
PP
1490 if (pretty->options.verbose) {
1491 ret = print_event_header_raw(pretty, event);
60535549
JD
1492 if (ret != BT_COMPONENT_STATUS_OK) {
1493 goto end;
1494 }
6a18b281 1495 }
6a18b281 1496
3228cc1d 1497 ret = print_stream_event_context(pretty, event);
6a18b281
MD
1498 if (ret != BT_COMPONENT_STATUS_OK) {
1499 goto end;
1500 }
6a18b281 1501
3228cc1d 1502 ret = print_event_context(pretty, event);
6a18b281
MD
1503 if (ret != BT_COMPONENT_STATUS_OK) {
1504 goto end;
1505 }
6a18b281 1506
3228cc1d 1507 ret = print_event_payload(pretty, event);
6a18b281
MD
1508 if (ret != BT_COMPONENT_STATUS_OK) {
1509 goto end;
1510 }
af9a82eb 1511
5280f742 1512 g_string_append_c(pretty->string, '\n');
08899d39 1513 if (flush_buf(pretty)) {
5280f742
PP
1514 ret = BT_COMPONENT_STATUS_ERROR;
1515 goto end;
1516 }
1517
af9a82eb
JG
1518end:
1519 return ret;
1520}
This page took 0.12298 seconds and 4 git commands to generate.