Fix: Dereference null return value
[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
30#include <babeltrace/ctf-ir/event.h>
31#include <babeltrace/ctf-ir/event-class.h>
6a18b281 32#include <babeltrace/ctf-ir/packet.h>
af9a82eb
JG
33#include <babeltrace/ctf-ir/stream.h>
34#include <babeltrace/ctf-ir/stream-class.h>
ac0c6bdd 35#include <babeltrace/ctf-ir/clock-class.h>
6a18b281
MD
36#include <babeltrace/ctf-ir/field-types.h>
37#include <babeltrace/ctf-ir/fields.h>
1556a1af 38#include <babeltrace/ctf-ir/trace.h>
d9f65f09 39#include <babeltrace/graph/notification-event.h>
da6febac
PP
40#include <babeltrace/graph/notification-discarded-events.h>
41#include <babeltrace/graph/notification-discarded-packets.h>
d9f65f09 42#include <babeltrace/graph/clock-class-priority-map.h>
3d9990ac 43#include <babeltrace/bitfield-internal.h>
ad96d936 44#include <babeltrace/common-internal.h>
58a2480d 45#include <babeltrace/compat/time-internal.h>
6a18b281 46#include <inttypes.h>
93a4161c 47#include <ctype.h>
3228cc1d 48#include "pretty.h"
af9a82eb 49
1556a1af
JG
50#define NSEC_PER_SEC 1000000000LL
51
5280f742 52#define COLOR_NAME BT_COMMON_COLOR_BOLD
da6febac 53#define COLOR_FIELD_NAME BT_COMMON_COLOR_FG_CYAN
5280f742
PP
54#define COLOR_RST BT_COMMON_COLOR_RESET
55#define COLOR_STRING_VALUE BT_COMMON_COLOR_BOLD
56#define COLOR_NUMBER_VALUE BT_COMMON_COLOR_BOLD
57#define COLOR_ENUM_MAPPING_NAME BT_COMMON_COLOR_BOLD
58#define COLOR_UNKNOWN BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_RED
da6febac 59#define COLOR_EVENT_NAME BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_MAGENTA
5280f742 60#define COLOR_TIMESTAMP BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_YELLOW
ad96d936 61
6a18b281
MD
62static inline
63const char *rem_(const char *str)
64{
65 if (str[0] == '_')
66 return &str[1];
67 else
68 return str;
69}
70
af9a82eb
JG
71struct timestamp {
72 int64_t real_timestamp; /* Relative to UNIX epoch. */
73 uint64_t clock_value; /* In cycles. */
74};
75
6a18b281 76static
3228cc1d 77enum bt_component_status print_field(struct pretty_component *pretty,
2b4c4a7c
JD
78 struct bt_ctf_field *field, bool print_names,
79 GQuark *filters_fields, int filter_array_len);
6a18b281 80
ad96d936 81static
3228cc1d 82void print_name_equal(struct pretty_component *pretty, const char *name)
ad96d936 83{
3228cc1d 84 if (pretty->use_colors) {
5280f742
PP
85 g_string_append_printf(pretty->string, "%s%s%s = ", COLOR_NAME,
86 name, COLOR_RST);
ad96d936 87 } else {
5280f742 88 g_string_append_printf(pretty->string, "%s = ", name);
ad96d936
PP
89 }
90}
91
92static
3228cc1d 93void print_field_name_equal(struct pretty_component *pretty, const char *name)
ad96d936 94{
3228cc1d 95 if (pretty->use_colors) {
5280f742
PP
96 g_string_append_printf(pretty->string, "%s%s%s = ",
97 COLOR_FIELD_NAME, name, COLOR_RST);
ad96d936 98 } else {
5280f742 99 g_string_append_printf(pretty->string, "%s = ", name);
ad96d936
PP
100 }
101}
102
af9a82eb 103static
3228cc1d 104void print_timestamp_cycles(struct pretty_component *pretty,
ac0c6bdd 105 struct bt_ctf_clock_class *clock_class,
af9a82eb
JG
106 struct bt_ctf_event *event)
107{
1556a1af
JG
108 int ret;
109 struct bt_ctf_clock_value *clock_value;
110 uint64_t cycles;
111
ac0c6bdd 112 clock_value = bt_ctf_event_get_clock_value(event, clock_class);
1556a1af 113 if (!clock_value) {
5280f742 114 g_string_append(pretty->string, "????????????????????");
1556a1af
JG
115 return;
116 }
117
118 ret = bt_ctf_clock_value_get_value(clock_value, &cycles);
119 bt_put(clock_value);
120 if (ret) {
5280f742
PP
121 // TODO: log, this is unexpected
122 g_string_append(pretty->string, "Error");
1556a1af
JG
123 return;
124 }
5280f742
PP
125
126 g_string_append_printf(pretty->string, "%020" PRIu64, cycles);
3af83b5a 127
3228cc1d
PP
128 if (pretty->last_cycles_timestamp != -1ULL) {
129 pretty->delta_cycles = cycles - pretty->last_cycles_timestamp;
3af83b5a 130 }
3228cc1d 131 pretty->last_cycles_timestamp = cycles;
af9a82eb
JG
132}
133
134static
3228cc1d 135void print_timestamp_wall(struct pretty_component *pretty,
da6febac 136 struct bt_ctf_clock_value *clock_value)
af9a82eb 137{
1556a1af 138 int ret;
1556a1af
JG
139 int64_t ts_nsec = 0; /* add configurable offset */
140 int64_t ts_sec = 0; /* add configurable offset */
141 uint64_t ts_sec_abs, ts_nsec_abs;
142 bool is_negative;
af9a82eb 143
1556a1af 144 if (!clock_value) {
5280f742 145 g_string_append(pretty->string, "??:??:??.?????????");
1556a1af
JG
146 return;
147 }
148
149 ret = bt_ctf_clock_value_get_value_ns_from_epoch(clock_value, &ts_nsec);
1556a1af 150 if (ret) {
5280f742
PP
151 // TODO: log, this is unexpected
152 g_string_append(pretty->string, "Error");
1556a1af
JG
153 return;
154 }
155
3228cc1d
PP
156 if (pretty->last_real_timestamp != -1ULL) {
157 pretty->delta_real_timestamp = ts_nsec - pretty->last_real_timestamp;
3af83b5a 158 }
3af83b5a 159
5280f742 160 pretty->last_real_timestamp = ts_nsec;
1556a1af
JG
161 ts_sec += ts_nsec / NSEC_PER_SEC;
162 ts_nsec = ts_nsec % NSEC_PER_SEC;
5280f742 163
1556a1af
JG
164 if (ts_sec >= 0 && ts_nsec >= 0) {
165 is_negative = false;
166 ts_sec_abs = ts_sec;
167 ts_nsec_abs = ts_nsec;
168 } else if (ts_sec > 0 && ts_nsec < 0) {
169 is_negative = false;
170 ts_sec_abs = ts_sec - 1;
171 ts_nsec_abs = NSEC_PER_SEC + ts_nsec;
172 } else if (ts_sec == 0 && ts_nsec < 0) {
173 is_negative = true;
174 ts_sec_abs = ts_sec;
175 ts_nsec_abs = -ts_nsec;
176 } else if (ts_sec < 0 && ts_nsec > 0) {
177 is_negative = true;
178 ts_sec_abs = -(ts_sec + 1);
179 ts_nsec_abs = NSEC_PER_SEC - ts_nsec;
180 } else if (ts_sec < 0 && ts_nsec == 0) {
181 is_negative = true;
182 ts_sec_abs = -ts_sec;
183 ts_nsec_abs = ts_nsec;
184 } else { /* (ts_sec < 0 && ts_nsec < 0) */
185 is_negative = true;
186 ts_sec_abs = -ts_sec;
187 ts_nsec_abs = -ts_nsec;
188 }
189
3228cc1d 190 if (!pretty->options.clock_seconds) {
1556a1af
JG
191 struct tm tm;
192 time_t time_s = (time_t) ts_sec_abs;
193
f1c99b12 194 if (is_negative && !pretty->negative_timestamp_warning_done) {
5280f742 195 // TODO: log instead
1556a1af 196 fprintf(stderr, "[warning] Fallback to [sec.ns] to print negative time value. Use --clock-seconds.\n");
f1c99b12 197 pretty->negative_timestamp_warning_done = true;
1556a1af
JG
198 goto seconds;
199 }
200
3228cc1d 201 if (!pretty->options.clock_gmt) {
1556a1af
JG
202 struct tm *res;
203
58a2480d 204 res = bt_localtime_r(&time_s, &tm);
1556a1af 205 if (!res) {
5280f742 206 // TODO: log instead
1556a1af
JG
207 fprintf(stderr, "[warning] Unable to get localtime.\n");
208 goto seconds;
209 }
210 } else {
211 struct tm *res;
212
58a2480d 213 res = bt_gmtime_r(&time_s, &tm);
1556a1af 214 if (!res) {
5280f742 215 // TODO: log instead
1556a1af
JG
216 fprintf(stderr, "[warning] Unable to get gmtime.\n");
217 goto seconds;
218 }
219 }
3228cc1d 220 if (pretty->options.clock_date) {
1556a1af
JG
221 char timestr[26];
222 size_t res;
223
224 /* Print date and time */
225 res = strftime(timestr, sizeof(timestr),
4d2a94f1 226 "%Y-%m-%d ", &tm);
1556a1af 227 if (!res) {
5280f742 228 // TODO: log instead
1556a1af
JG
229 fprintf(stderr, "[warning] Unable to print ascii time.\n");
230 goto seconds;
231 }
5280f742
PP
232
233 g_string_append(pretty->string, timestr);
1556a1af 234 }
5280f742 235
1556a1af 236 /* Print time in HH:MM:SS.ns */
5280f742
PP
237 g_string_append_printf(pretty->string,
238 "%02d:%02d:%02d.%09" PRIu64, tm.tm_hour, tm.tm_min,
239 tm.tm_sec, ts_nsec_abs);
1556a1af
JG
240 goto end;
241 }
242seconds:
5280f742
PP
243 g_string_append_printf(pretty->string, "%s%" PRId64 ".%09" PRIu64,
244 is_negative ? "-" : "", ts_sec_abs, ts_nsec_abs);
1556a1af
JG
245end:
246 return;
af9a82eb
JG
247}
248
249static
3228cc1d 250enum bt_component_status print_event_timestamp(struct pretty_component *pretty,
d9f65f09
PP
251 struct bt_ctf_event *event,
252 struct bt_clock_class_priority_map *cc_prio_map,
253 bool *start_line)
af9a82eb 254{
3228cc1d 255 bool print_names = pretty->options.print_header_field_names;
af9a82eb 256 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
6a18b281 257 struct bt_ctf_stream *stream = NULL;
1556a1af
JG
258 struct bt_ctf_stream_class *stream_class = NULL;
259 struct bt_ctf_trace *trace = NULL;
ac0c6bdd 260 struct bt_ctf_clock_class *clock_class = NULL;
af9a82eb
JG
261
262 stream = bt_ctf_event_get_stream(event);
263 if (!stream) {
264 ret = BT_COMPONENT_STATUS_ERROR;
265 goto end;
266 }
267
1556a1af 268 stream_class = bt_ctf_stream_get_class(stream);
f504043c
MD
269 if (!stream_class) {
270 ret = BT_COMPONENT_STATUS_ERROR;
271 goto end;
272 }
1556a1af 273 trace = bt_ctf_stream_class_get_trace(stream_class);
f504043c
MD
274 if (!trace) {
275 ret = BT_COMPONENT_STATUS_ERROR;
276 goto end;
277 }
d9f65f09
PP
278
279 if (bt_clock_class_priority_map_get_clock_class_count(cc_prio_map) == 0) {
280 /* No clock class: skip the timestamp without an error */
281 goto end;
282 }
283
284 clock_class =
285 bt_clock_class_priority_map_get_highest_priority_clock_class(
286 cc_prio_map);
ac0c6bdd 287 if (!clock_class) {
f504043c
MD
288 ret = BT_COMPONENT_STATUS_ERROR;
289 goto end;
290 }
af9a82eb 291
ad96d936 292 if (print_names) {
3228cc1d 293 print_name_equal(pretty, "timestamp");
ad96d936 294 } else {
5280f742 295 g_string_append(pretty->string, "[");
ad96d936 296 }
3228cc1d 297 if (pretty->use_colors) {
5280f742 298 g_string_append(pretty->string, COLOR_TIMESTAMP);
ad96d936 299 }
3228cc1d
PP
300 if (pretty->options.print_timestamp_cycles) {
301 print_timestamp_cycles(pretty, clock_class, event);
af9a82eb 302 } else {
da6febac
PP
303 struct bt_ctf_clock_value *clock_value =
304 bt_ctf_event_get_clock_value(event, clock_class);
305
306 print_timestamp_wall(pretty, clock_value);
307 bt_put(clock_value);
af9a82eb 308 }
3228cc1d 309 if (pretty->use_colors) {
5280f742 310 g_string_append(pretty->string, COLOR_RST);
ad96d936 311 }
af9a82eb 312
c3c30b08 313 if (!print_names)
5280f742 314 g_string_append(pretty->string, "] ");
c3c30b08 315
3228cc1d 316 if (pretty->options.print_delta_field) {
ad96d936 317 if (print_names) {
5280f742 318 g_string_append(pretty->string, ", ");
3228cc1d 319 print_name_equal(pretty, "delta");
ad96d936 320 } else {
5280f742 321 g_string_append(pretty->string, "(");
ad96d936 322 }
3228cc1d
PP
323 if (pretty->options.print_timestamp_cycles) {
324 if (pretty->delta_cycles == -1ULL) {
5280f742
PP
325 g_string_append(pretty->string,
326 "+??????????\?\?) "); /* Not a trigraph. */
3af83b5a 327 } else {
5280f742
PP
328 g_string_append_printf(pretty->string,
329 "+%012" PRIu64, pretty->delta_cycles);
3af83b5a
MD
330 }
331 } else {
3228cc1d 332 if (pretty->delta_real_timestamp != -1ULL) {
3af83b5a 333 uint64_t delta_sec, delta_nsec, delta;
f504043c 334
3228cc1d 335 delta = pretty->delta_real_timestamp;
3af83b5a
MD
336 delta_sec = delta / NSEC_PER_SEC;
337 delta_nsec = delta % NSEC_PER_SEC;
5280f742
PP
338 g_string_append_printf(pretty->string,
339 "+%" PRIu64 ".%09" PRIu64,
3af83b5a
MD
340 delta_sec, delta_nsec);
341 } else {
5280f742 342 g_string_append(pretty->string, "+?.?????????");
3af83b5a
MD
343 }
344 }
345 if (!print_names) {
5280f742 346 g_string_append(pretty->string, ") ");
3af83b5a
MD
347 }
348 }
349 *start_line = !print_names;
f504043c 350
af9a82eb
JG
351end:
352 bt_put(stream);
ac0c6bdd 353 bt_put(clock_class);
1556a1af
JG
354 bt_put(stream_class);
355 bt_put(trace);
af9a82eb
JG
356 return ret;
357}
358
6a18b281 359static
3228cc1d 360enum bt_component_status print_event_header(struct pretty_component *pretty,
d9f65f09
PP
361 struct bt_ctf_event *event,
362 struct bt_clock_class_priority_map *cc_prio_map)
af9a82eb 363{
3228cc1d 364 bool print_names = pretty->options.print_header_field_names;
6a18b281
MD
365 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
366 struct bt_ctf_event_class *event_class = NULL;
c3c30b08
MD
367 struct bt_ctf_stream_class *stream_class = NULL;
368 struct bt_ctf_trace *trace_class = NULL;
60535549 369 int dom_print = 0;
af9a82eb 370
6a18b281
MD
371 event_class = bt_ctf_event_get_class(event);
372 if (!event_class) {
373 ret = BT_COMPONENT_STATUS_ERROR;
374 goto end;
375 }
c3c30b08
MD
376 stream_class = bt_ctf_event_class_get_stream_class(event_class);
377 if (!stream_class) {
378 ret = BT_COMPONENT_STATUS_ERROR;
379 goto end;
380 }
381 trace_class = bt_ctf_stream_class_get_trace(stream_class);
382 if (!trace_class) {
383 ret = BT_COMPONENT_STATUS_ERROR;
384 goto end;
385 }
d9f65f09
PP
386 ret = print_event_timestamp(pretty, event, cc_prio_map,
387 &pretty->start_line);
af9a82eb
JG
388 if (ret != BT_COMPONENT_STATUS_OK) {
389 goto end;
390 }
3228cc1d 391 if (pretty->options.print_trace_field) {
c3c30b08
MD
392 const char *name;
393
394 name = bt_ctf_trace_get_name(trace_class);
395 if (name) {
3228cc1d 396 if (!pretty->start_line) {
5280f742 397 g_string_append(pretty->string, ", ");
c3c30b08 398 }
c3c30b08 399 if (print_names) {
3228cc1d 400 print_name_equal(pretty, "trace");
c3c30b08 401 }
5280f742
PP
402
403 g_string_append(pretty->string, name);
404
60535549 405 if (!print_names) {
5280f742 406 g_string_append(pretty->string, " ");
60535549 407 }
c3c30b08
MD
408 }
409 }
3228cc1d 410 if (pretty->options.print_trace_hostname_field) {
c3c30b08
MD
411 struct bt_value *hostname_str;
412
413 hostname_str = bt_ctf_trace_get_environment_field_value_by_name(trace_class,
414 "hostname");
415 if (hostname_str) {
416 const char *str;
417
3228cc1d 418 if (!pretty->start_line) {
5280f742 419 g_string_append(pretty->string, ", ");
c3c30b08 420 }
c3c30b08 421 if (print_names) {
3228cc1d 422 print_name_equal(pretty, "trace:hostname");
c3c30b08
MD
423 }
424 if (bt_value_string_get(hostname_str, &str)
425 == BT_VALUE_STATUS_OK) {
5280f742 426 g_string_append(pretty->string, str);
c3c30b08
MD
427 }
428 bt_put(hostname_str);
60535549 429 dom_print = 1;
c3c30b08
MD
430 }
431 }
3228cc1d 432 if (pretty->options.print_trace_domain_field) {
c3c30b08
MD
433 struct bt_value *domain_str;
434
435 domain_str = bt_ctf_trace_get_environment_field_value_by_name(trace_class,
436 "domain");
437 if (domain_str) {
438 const char *str;
439
3228cc1d 440 if (!pretty->start_line) {
5280f742 441 g_string_append(pretty->string, ", ");
c3c30b08 442 }
c3c30b08 443 if (print_names) {
3228cc1d 444 print_name_equal(pretty, "trace:domain");
60535549 445 } else if (dom_print) {
5280f742 446 g_string_append(pretty->string, ":");
c3c30b08
MD
447 }
448 if (bt_value_string_get(domain_str, &str)
449 == BT_VALUE_STATUS_OK) {
5280f742 450 g_string_append(pretty->string, str);
c3c30b08
MD
451 }
452 bt_put(domain_str);
60535549 453 dom_print = 1;
c3c30b08
MD
454 }
455 }
3228cc1d 456 if (pretty->options.print_trace_procname_field) {
c3c30b08
MD
457 struct bt_value *procname_str;
458
459 procname_str = bt_ctf_trace_get_environment_field_value_by_name(trace_class,
460 "procname");
461 if (procname_str) {
462 const char *str;
463
3228cc1d 464 if (!pretty->start_line) {
5280f742 465 g_string_append(pretty->string, ", ");
c3c30b08 466 }
c3c30b08 467 if (print_names) {
3228cc1d 468 print_name_equal(pretty, "trace:procname");
60535549 469 } else if (dom_print) {
5280f742 470 g_string_append(pretty->string, ":");
c3c30b08
MD
471 }
472 if (bt_value_string_get(procname_str, &str)
473 == BT_VALUE_STATUS_OK) {
5280f742 474 g_string_append(pretty->string, str);
c3c30b08
MD
475 }
476 bt_put(procname_str);
60535549 477 dom_print = 1;
c3c30b08
MD
478 }
479 }
3228cc1d 480 if (pretty->options.print_trace_vpid_field) {
c3c30b08
MD
481 struct bt_value *vpid_value;
482
483 vpid_value = bt_ctf_trace_get_environment_field_value_by_name(trace_class,
484 "vpid");
485 if (vpid_value) {
486 int64_t value;
487
3228cc1d 488 if (!pretty->start_line) {
5280f742 489 g_string_append(pretty->string, ", ");
c3c30b08 490 }
c3c30b08 491 if (print_names) {
3228cc1d 492 print_name_equal(pretty, "trace:vpid");
60535549 493 } else if (dom_print) {
5280f742 494 g_string_append(pretty->string, ":");
c3c30b08
MD
495 }
496 if (bt_value_integer_get(vpid_value, &value)
497 == BT_VALUE_STATUS_OK) {
5280f742 498 g_string_append_printf(pretty->string, "(%" PRId64 ")", value);
c3c30b08
MD
499 }
500 bt_put(vpid_value);
60535549 501 dom_print = 1;
c3c30b08
MD
502 }
503 }
3228cc1d 504 if (pretty->options.print_loglevel_field) {
9cf5d083
PP
505 static const char *log_level_names[] = {
506 [ BT_CTF_EVENT_CLASS_LOG_LEVEL_EMERGENCY ] = "TRACE_EMERG",
507 [ BT_CTF_EVENT_CLASS_LOG_LEVEL_ALERT ] = "TRACE_ALERT",
508 [ BT_CTF_EVENT_CLASS_LOG_LEVEL_CRITICAL ] = "TRACE_CRIT",
509 [ BT_CTF_EVENT_CLASS_LOG_LEVEL_ERROR ] = "TRACE_ERR",
510 [ BT_CTF_EVENT_CLASS_LOG_LEVEL_WARNING ] = "TRACE_WARNING",
511 [ BT_CTF_EVENT_CLASS_LOG_LEVEL_NOTICE ] = "TRACE_NOTICE",
512 [ BT_CTF_EVENT_CLASS_LOG_LEVEL_INFO ] = "TRACE_INFO",
513 [ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM ] = "TRACE_DEBUG_SYSTEM",
514 [ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM ] = "TRACE_DEBUG_PROGRAM",
515 [ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS ] = "TRACE_DEBUG_PROCESS",
516 [ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE ] = "TRACE_DEBUG_MODULE",
517 [ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT ] = "TRACE_DEBUG_UNIT",
518 [ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION ] = "TRACE_DEBUG_FUNCTION",
519 [ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE ] = "TRACE_DEBUG_LINE",
520 [ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG ] = "TRACE_DEBUG",
521 };
522 enum bt_ctf_event_class_log_level log_level;
523 const char *log_level_str = NULL;
524
525 log_level = bt_ctf_event_class_get_log_level(event_class);
526 assert(log_level != BT_CTF_EVENT_CLASS_LOG_LEVEL_UNKNOWN);
527 if (log_level != BT_CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED) {
528 log_level_str = log_level_names[log_level];
529 }
c3c30b08 530
9cf5d083 531 if (log_level_str) {
3228cc1d 532 if (!pretty->start_line) {
5280f742 533 g_string_append(pretty->string, ", ");
c3c30b08 534 }
c3c30b08 535 if (print_names) {
3228cc1d 536 print_name_equal(pretty, "loglevel");
60535549 537 } else if (dom_print) {
5280f742 538 g_string_append(pretty->string, ":");
c3c30b08 539 }
9cf5d083
PP
540
541 g_string_append(pretty->string, log_level_str);
542 g_string_append_printf(
543 pretty->string, " (%d)", (int) log_level);
60535549 544 dom_print = 1;
c3c30b08
MD
545 }
546 }
3228cc1d 547 if (pretty->options.print_emf_field) {
9cf5d083 548 const char *uri_str;
c3c30b08 549
9cf5d083 550 uri_str = bt_ctf_event_class_get_emf_uri(event_class);
c3c30b08 551 if (uri_str) {
3228cc1d 552 if (!pretty->start_line) {
5280f742 553 g_string_append(pretty->string, ", ");
c3c30b08 554 }
c3c30b08 555 if (print_names) {
3228cc1d 556 print_name_equal(pretty, "model.emf.uri");
60535549 557 } else if (dom_print) {
5280f742 558 g_string_append(pretty->string, ":");
c3c30b08 559 }
c3c30b08 560
9cf5d083 561 g_string_append(pretty->string, uri_str);
60535549 562 dom_print = 1;
c3c30b08
MD
563 }
564 }
60535549 565 if (dom_print && !print_names) {
5280f742 566 g_string_append(pretty->string, " ");
60535549 567 }
3228cc1d 568 if (!pretty->start_line) {
5280f742 569 g_string_append(pretty->string, ", ");
c3c30b08 570 }
3228cc1d 571 pretty->start_line = true;
6a18b281 572 if (print_names) {
3228cc1d 573 print_name_equal(pretty, "name");
ad96d936 574 }
3228cc1d 575 if (pretty->use_colors) {
5280f742 576 g_string_append(pretty->string, COLOR_EVENT_NAME);
6a18b281 577 }
5280f742 578 g_string_append(pretty->string, bt_ctf_event_class_get_name(event_class));
3228cc1d 579 if (pretty->use_colors) {
5280f742 580 g_string_append(pretty->string, COLOR_RST);
ad96d936 581 }
60535549 582 if (!print_names) {
5280f742 583 g_string_append(pretty->string, ": ");
60535549 584 } else {
5280f742 585 g_string_append(pretty->string, ", ");
60535549 586 }
af9a82eb 587end:
c3c30b08
MD
588 bt_put(trace_class);
589 bt_put(stream_class);
6a18b281
MD
590 bt_put(event_class);
591 return ret;
592}
593
594static
3228cc1d 595enum bt_component_status print_integer(struct pretty_component *pretty,
6a18b281
MD
596 struct bt_ctf_field *field)
597{
598 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
599 struct bt_ctf_field_type *field_type = NULL;
600 enum bt_ctf_integer_base base;
601 enum bt_ctf_string_encoding encoding;
602 int signedness;
603 union {
604 uint64_t u;
605 int64_t s;
606 } v;
ad96d936 607 bool rst_color = false;
6a18b281
MD
608
609 field_type = bt_ctf_field_get_type(field);
610 if (!field_type) {
611 ret = BT_COMPONENT_STATUS_ERROR;
612 goto end;
613 }
614 signedness = bt_ctf_field_type_integer_get_signed(field_type);
615 if (signedness < 0) {
616 ret = BT_COMPONENT_STATUS_ERROR;
617 goto end;
618 }
619 if (!signedness) {
620 if (bt_ctf_field_unsigned_integer_get_value(field, &v.u) < 0) {
621 ret = BT_COMPONENT_STATUS_ERROR;
622 goto end;
623 }
624 } else {
625 if (bt_ctf_field_signed_integer_get_value(field, &v.s) < 0) {
626 ret = BT_COMPONENT_STATUS_ERROR;
627 goto end;
628 }
629 }
630
631 encoding = bt_ctf_field_type_integer_get_encoding(field_type);
632 switch (encoding) {
633 case BT_CTF_STRING_ENCODING_UTF8:
634 case BT_CTF_STRING_ENCODING_ASCII:
5280f742 635 g_string_append_c(pretty->tmp_string, (int) v.u);
6a18b281
MD
636 goto end;
637 case BT_CTF_STRING_ENCODING_NONE:
638 case BT_CTF_STRING_ENCODING_UNKNOWN:
639 break;
640 default:
641 ret = BT_COMPONENT_STATUS_ERROR;
642 goto end;
643 }
644
3228cc1d 645 if (pretty->use_colors) {
5280f742 646 g_string_append(pretty->string, COLOR_NUMBER_VALUE);
ad96d936
PP
647 rst_color = true;
648 }
649
6a18b281
MD
650 base = bt_ctf_field_type_integer_get_base(field_type);
651 switch (base) {
652 case BT_CTF_INTEGER_BASE_BINARY:
653 {
654 int bitnr, len;
655
656 len = bt_ctf_field_type_integer_get_size(field_type);
657 if (len < 0) {
658 ret = BT_COMPONENT_STATUS_ERROR;
659 goto end;
660 }
5280f742 661 g_string_append(pretty->string, "0b");
6a18b281
MD
662 v.u = _bt_piecewise_lshift(v.u, 64 - len);
663 for (bitnr = 0; bitnr < len; bitnr++) {
5280f742 664 g_string_append_printf(pretty->string, "%u", (v.u & (1ULL << 63)) ? 1 : 0);
6a18b281
MD
665 v.u = _bt_piecewise_lshift(v.u, 1);
666 }
667 break;
668 }
669 case BT_CTF_INTEGER_BASE_OCTAL:
670 {
671 if (signedness) {
672 int len;
673
674 len = bt_ctf_field_type_integer_get_size(field_type);
675 if (len < 0) {
676 ret = BT_COMPONENT_STATUS_ERROR;
677 goto end;
678 }
679 if (len < 64) {
680 size_t rounded_len;
681
682 assert(len != 0);
683 /* Round length to the nearest 3-bit */
684 rounded_len = (((len - 1) / 3) + 1) * 3;
685 v.u &= ((uint64_t) 1 << rounded_len) - 1;
686 }
687 }
688
5280f742 689 g_string_append_printf(pretty->string, "0%" PRIo64, v.u);
6a18b281
MD
690 break;
691 }
692 case BT_CTF_INTEGER_BASE_DECIMAL:
d7c5164e 693 case BT_CTF_INTEGER_BASE_UNSPECIFIED:
6a18b281 694 if (!signedness) {
5280f742 695 g_string_append_printf(pretty->string, "%" PRIu64, v.u);
6a18b281 696 } else {
5280f742 697 g_string_append_printf(pretty->string, "%" PRId64, v.s);
6a18b281
MD
698 }
699 break;
700 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
701 {
702 int len;
703
704 len = bt_ctf_field_type_integer_get_size(field_type);
705 if (len < 0) {
706 ret = BT_COMPONENT_STATUS_ERROR;
707 goto end;
708 }
709 if (len < 64) {
710 /* Round length to the nearest nibble */
711 uint8_t rounded_len = ((len + 3) & ~0x3);
712
713 v.u &= ((uint64_t) 1 << rounded_len) - 1;
714 }
715
5280f742 716 g_string_append_printf(pretty->string, "0x%" PRIX64, v.u);
6a18b281
MD
717 break;
718 }
719 default:
720 ret = BT_COMPONENT_STATUS_ERROR;
721 goto end;
722 }
723end:
ad96d936 724 if (rst_color) {
5280f742 725 g_string_append(pretty->string, COLOR_RST);
ad96d936 726 }
6a18b281
MD
727 bt_put(field_type);
728 return ret;
729}
730
93a4161c 731static
3228cc1d 732void print_escape_string(struct pretty_component *pretty, const char *str)
93a4161c
JD
733{
734 int i;
735
5280f742
PP
736 g_string_append_c(pretty->string, '"');
737
93a4161c
JD
738 for (i = 0; i < strlen(str); i++) {
739 /* Escape sequences not recognized by iscntrl(). */
740 switch (str[i]) {
741 case '\\':
5280f742 742 g_string_append(pretty->string, "\\\\");
93a4161c
JD
743 continue;
744 case '\'':
5280f742 745 g_string_append(pretty->string, "\\\'");
93a4161c
JD
746 continue;
747 case '\"':
5280f742 748 g_string_append(pretty->string, "\\\"");
93a4161c
JD
749 continue;
750 case '\?':
5280f742 751 g_string_append(pretty->string, "\\\?");
93a4161c
JD
752 continue;
753 }
754
755 /* Standard characters. */
756 if (!iscntrl(str[i])) {
5280f742 757 g_string_append_c(pretty->string, str[i]);
93a4161c
JD
758 continue;
759 }
760
761 switch (str[i]) {
762 case '\0':
5280f742 763 g_string_append(pretty->string, "\\0");
93a4161c
JD
764 break;
765 case '\a':
5280f742 766 g_string_append(pretty->string, "\\a");
93a4161c
JD
767 break;
768 case '\b':
5280f742 769 g_string_append(pretty->string, "\\b");
93a4161c
JD
770 break;
771 case '\e':
5280f742 772 g_string_append(pretty->string, "\\e");
93a4161c
JD
773 break;
774 case '\f':
5280f742 775 g_string_append(pretty->string, "\\f");
93a4161c
JD
776 break;
777 case '\n':
5280f742 778 g_string_append(pretty->string, "\\n");
93a4161c
JD
779 break;
780 case '\r':
5280f742 781 g_string_append(pretty->string, "\\r");
93a4161c
JD
782 break;
783 case '\t':
5280f742 784 g_string_append(pretty->string, "\\t");
93a4161c
JD
785 break;
786 case '\v':
5280f742 787 g_string_append(pretty->string, "\\v");
93a4161c
JD
788 break;
789 default:
790 /* Unhandled control-sequence, print as hex. */
5280f742 791 g_string_append_printf(pretty->string, "\\x%02x", str[i]);
93a4161c
JD
792 break;
793 }
794 }
5280f742
PP
795
796 g_string_append_c(pretty->string, '"');
93a4161c
JD
797}
798
6a18b281 799static
3228cc1d 800enum bt_component_status print_enum(struct pretty_component *pretty,
6a18b281
MD
801 struct bt_ctf_field *field)
802{
803 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
804 struct bt_ctf_field *container_field = NULL;
96e8f959
MD
805 struct bt_ctf_field_type *enumeration_field_type = NULL;
806 struct bt_ctf_field_type *container_field_type = NULL;
807 struct bt_ctf_field_type_enumeration_mapping_iterator *iter = NULL;
808 int nr_mappings = 0;
809 int is_signed;
810
811 enumeration_field_type = bt_ctf_field_get_type(field);
812 if (!enumeration_field_type) {
813 ret = BT_COMPONENT_STATUS_ERROR;
814 goto end;
815 }
6a18b281
MD
816 container_field = bt_ctf_field_enumeration_get_container(field);
817 if (!container_field) {
818 ret = BT_COMPONENT_STATUS_ERROR;
819 goto end;
820 }
96e8f959
MD
821 container_field_type = bt_ctf_field_get_type(container_field);
822 if (!container_field_type) {
823 ret = BT_COMPONENT_STATUS_ERROR;
824 goto end;
825 }
826 is_signed = bt_ctf_field_type_integer_get_signed(container_field_type);
827 if (is_signed < 0) {
828 ret = BT_COMPONENT_STATUS_ERROR;
829 goto end;
830 }
831 if (is_signed) {
832 int64_t value;
833
834 if (bt_ctf_field_signed_integer_get_value(container_field,
835 &value)) {
836 ret = BT_COMPONENT_STATUS_ERROR;
837 goto end;
838 }
839 iter = bt_ctf_field_type_enumeration_find_mappings_by_signed_value(
840 enumeration_field_type, value);
6a18b281 841 } else {
96e8f959
MD
842 uint64_t value;
843
844 if (bt_ctf_field_unsigned_integer_get_value(container_field,
845 &value)) {
846 ret = BT_COMPONENT_STATUS_ERROR;
847 goto end;
848 }
849 iter = bt_ctf_field_type_enumeration_find_mappings_by_unsigned_value(
850 enumeration_field_type, value);
851 }
852 if (!iter) {
853 ret = BT_COMPONENT_STATUS_ERROR;
854 goto end;
855 }
5280f742 856 g_string_append(pretty->string, "( ");
96e8f959
MD
857 for (;;) {
858 const char *mapping_name;
859
860 if (bt_ctf_field_type_enumeration_mapping_iterator_get_signed(
861 iter, &mapping_name, NULL, NULL) < 0) {
862 ret = BT_COMPONENT_STATUS_ERROR;
863 goto end;
864 }
865 if (nr_mappings++)
5280f742 866 g_string_append(pretty->string, ", ");
3228cc1d 867 if (pretty->use_colors) {
5280f742 868 g_string_append(pretty->string, COLOR_ENUM_MAPPING_NAME);
ad96d936 869 }
3228cc1d
PP
870 print_escape_string(pretty, mapping_name);
871 if (pretty->use_colors) {
5280f742 872 g_string_append(pretty->string, COLOR_RST);
ad96d936 873 }
96e8f959
MD
874 if (bt_ctf_field_type_enumeration_mapping_iterator_next(iter) < 0) {
875 break;
876 }
877 }
878 if (!nr_mappings) {
3228cc1d 879 if (pretty->use_colors) {
5280f742 880 g_string_append(pretty->string, COLOR_UNKNOWN);
ad96d936 881 }
5280f742 882 g_string_append(pretty->string, "<unknown>");
3228cc1d 883 if (pretty->use_colors) {
5280f742 884 g_string_append(pretty->string, COLOR_RST);
ad96d936 885 }
6a18b281 886 }
5280f742 887 g_string_append(pretty->string, " : container = ");
3228cc1d 888 ret = print_integer(pretty, container_field);
6a18b281
MD
889 if (ret != BT_COMPONENT_STATUS_OK) {
890 goto end;
891 }
5280f742 892 g_string_append(pretty->string, " )");
6a18b281 893end:
96e8f959
MD
894 bt_put(iter);
895 bt_put(container_field_type);
6a18b281 896 bt_put(container_field);
96e8f959 897 bt_put(enumeration_field_type);
6a18b281
MD
898 return ret;
899}
900
2b4c4a7c 901static
3228cc1d 902int filter_field_name(struct pretty_component *pretty, const char *field_name,
2b4c4a7c
JD
903 GQuark *filter_fields, int filter_array_len)
904{
905 int i;
906 GQuark field_quark = g_quark_try_string(field_name);
907
3228cc1d 908 if (!field_quark || pretty->options.verbose) {
2b4c4a7c
JD
909 return 1;
910 }
911
912 for (i = 0; i < filter_array_len; i++) {
913 if (field_quark == filter_fields[i]) {
914 return 0;
915 }
916 }
917 return 1;
918}
919
6a18b281 920static
3228cc1d 921enum bt_component_status print_struct_field(struct pretty_component *pretty,
6a18b281
MD
922 struct bt_ctf_field *_struct,
923 struct bt_ctf_field_type *struct_type,
2b4c4a7c
JD
924 int i, bool print_names, int *nr_printed_fields,
925 GQuark *filter_fields, int filter_array_len)
6a18b281
MD
926{
927 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
928 const char *field_name;
929 struct bt_ctf_field *field = NULL;
930 struct bt_ctf_field_type *field_type = NULL;;
931
932 field = bt_ctf_field_structure_get_field_by_index(_struct, i);
933 if (!field) {
934 ret = BT_COMPONENT_STATUS_ERROR;
935 goto end;
936 }
937 if (bt_ctf_field_type_structure_get_field(struct_type,
938 &field_name, &field_type, i) < 0) {
939 ret = BT_COMPONENT_STATUS_ERROR;
940 goto end;
941 }
942
3228cc1d 943 if (filter_fields && !filter_field_name(pretty, field_name,
2b4c4a7c
JD
944 filter_fields, filter_array_len)) {
945 ret = BT_COMPONENT_STATUS_OK;
946 goto end;
947 }
948
949 if (*nr_printed_fields > 0) {
5280f742 950 g_string_append(pretty->string, ", ");
6a18b281 951 } else {
5280f742 952 g_string_append(pretty->string, " ");
6a18b281
MD
953 }
954 if (print_names) {
3228cc1d 955 print_field_name_equal(pretty, rem_(field_name));
6a18b281 956 }
3228cc1d 957 ret = print_field(pretty, field, print_names, NULL, 0);
2b4c4a7c 958 *nr_printed_fields += 1;
6a18b281
MD
959end:
960 bt_put(field_type);
961 bt_put(field);
962 return ret;
963}
964
965static
3228cc1d 966enum bt_component_status print_struct(struct pretty_component *pretty,
2b4c4a7c
JD
967 struct bt_ctf_field *_struct, bool print_names,
968 GQuark *filter_fields, int filter_array_len)
6a18b281
MD
969{
970 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
971 struct bt_ctf_field_type *struct_type = NULL;
2b4c4a7c 972 int nr_fields, i, nr_printed_fields;
6a18b281
MD
973
974 struct_type = bt_ctf_field_get_type(_struct);
975 if (!struct_type) {
976 ret = BT_COMPONENT_STATUS_ERROR;
977 goto end;
978 }
979 nr_fields = bt_ctf_field_type_structure_get_field_count(struct_type);
980 if (nr_fields < 0) {
981 ret = BT_COMPONENT_STATUS_ERROR;
982 goto end;
983 }
5280f742 984 g_string_append(pretty->string, "{");
3228cc1d 985 pretty->depth++;
2b4c4a7c 986 nr_printed_fields = 0;
6a18b281 987 for (i = 0; i < nr_fields; i++) {
3228cc1d 988 ret = print_struct_field(pretty, _struct, struct_type, i,
2b4c4a7c
JD
989 print_names, &nr_printed_fields, filter_fields,
990 filter_array_len);
6a18b281
MD
991 if (ret != BT_COMPONENT_STATUS_OK) {
992 goto end;
993 }
994 }
3228cc1d 995 pretty->depth--;
5280f742 996 g_string_append(pretty->string, " }");
6a18b281
MD
997end:
998 bt_put(struct_type);
999 return ret;
1000}
1001
1002static
3228cc1d 1003enum bt_component_status print_array_field(struct pretty_component *pretty,
6a18b281
MD
1004 struct bt_ctf_field *array, uint64_t i,
1005 bool is_string, bool print_names)
1006{
1007 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
1008 struct bt_ctf_field *field = NULL;
1009
1010 if (!is_string) {
1011 if (i != 0) {
5280f742 1012 g_string_append(pretty->string, ", ");
6a18b281 1013 } else {
5280f742 1014 g_string_append(pretty->string, " ");
6a18b281 1015 }
60535549 1016 if (print_names) {
5280f742 1017 g_string_append_printf(pretty->string, "[%" PRIu64 "] = ", i);
60535549 1018 }
6a18b281
MD
1019 }
1020 field = bt_ctf_field_array_get_field(array, i);
1021 if (!field) {
1022 ret = BT_COMPONENT_STATUS_ERROR;
1023 goto end;
1024 }
3228cc1d 1025 ret = print_field(pretty, field, print_names, NULL, 0);
6a18b281
MD
1026end:
1027 bt_put(field);
1028 return ret;
1029}
1030
1031static
3228cc1d 1032enum bt_component_status print_array(struct pretty_component *pretty,
6a18b281
MD
1033 struct bt_ctf_field *array, bool print_names)
1034{
1035 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
1036 struct bt_ctf_field_type *array_type = NULL, *field_type = NULL;
1487a16a 1037 enum bt_ctf_field_type_id type_id;
6a18b281
MD
1038 int64_t len;
1039 uint64_t i;
1040 bool is_string = false;
1041
1042 array_type = bt_ctf_field_get_type(array);
1043 if (!array_type) {
1044 ret = BT_COMPONENT_STATUS_ERROR;
1045 goto end;
1046 }
1047 field_type = bt_ctf_field_type_array_get_element_type(array_type);
1048 if (!field_type) {
1049 ret = BT_COMPONENT_STATUS_ERROR;
1050 goto end;
1051 }
1052 len = bt_ctf_field_type_array_get_length(array_type);
1053 if (len < 0) {
1054 ret = BT_COMPONENT_STATUS_ERROR;
1055 goto end;
1056 }
1057 type_id = bt_ctf_field_type_get_type_id(field_type);
1487a16a 1058 if (type_id == BT_CTF_FIELD_TYPE_ID_INTEGER) {
6a18b281
MD
1059 enum bt_ctf_string_encoding encoding;
1060
1061 encoding = bt_ctf_field_type_integer_get_encoding(field_type);
1062 if (encoding == BT_CTF_STRING_ENCODING_UTF8
1063 || encoding == BT_CTF_STRING_ENCODING_ASCII) {
1064 int integer_len, integer_alignment;
1065
1066 integer_len = bt_ctf_field_type_integer_get_size(field_type);
1067 if (integer_len < 0) {
1068 return BT_COMPONENT_STATUS_ERROR;
1069 }
1070 integer_alignment = bt_ctf_field_type_get_alignment(field_type);
1071 if (integer_alignment < 0) {
1072 return BT_COMPONENT_STATUS_ERROR;
1073 }
1074 if (integer_len == CHAR_BIT
1075 && integer_alignment == CHAR_BIT) {
1076 is_string = true;
1077 }
1078 }
1079 }
1080
1081 if (is_string) {
5280f742 1082 g_string_assign(pretty->tmp_string, "");
6a18b281 1083 } else {
5280f742 1084 g_string_append(pretty->string, "[");
6a18b281
MD
1085 }
1086
3228cc1d 1087 pretty->depth++;
6a18b281 1088 for (i = 0; i < len; i++) {
3228cc1d 1089 ret = print_array_field(pretty, array, i, is_string, print_names);
6a18b281
MD
1090 if (ret != BT_COMPONENT_STATUS_OK) {
1091 goto end;
1092 }
1093 }
3228cc1d 1094 pretty->depth--;
6a18b281
MD
1095
1096 if (is_string) {
3228cc1d 1097 if (pretty->use_colors) {
5280f742 1098 g_string_append(pretty->string, COLOR_STRING_VALUE);
ad96d936 1099 }
5280f742 1100 print_escape_string(pretty, pretty->tmp_string->str);
3228cc1d 1101 if (pretty->use_colors) {
5280f742 1102 g_string_append(pretty->string, COLOR_RST);
ad96d936 1103 }
6a18b281 1104 } else {
5280f742 1105 g_string_append(pretty->string, " ]");
6a18b281
MD
1106 }
1107end:
1108 bt_put(field_type);
1109 bt_put(array_type);
1110 return ret;
1111}
1112
1113static
3228cc1d 1114enum bt_component_status print_sequence_field(struct pretty_component *pretty,
6a18b281
MD
1115 struct bt_ctf_field *seq, uint64_t i,
1116 bool is_string, bool print_names)
1117{
1118 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
1119 struct bt_ctf_field *field = NULL;
1120
1121 if (!is_string) {
1122 if (i != 0) {
5280f742 1123 g_string_append(pretty->string, ", ");
6a18b281 1124 } else {
5280f742 1125 g_string_append(pretty->string, " ");
6a18b281 1126 }
60535549 1127 if (print_names) {
5280f742 1128 g_string_append_printf(pretty->string, "[%" PRIu64 "] = ", i);
60535549 1129 }
6a18b281
MD
1130 }
1131 field = bt_ctf_field_sequence_get_field(seq, i);
1132 if (!field) {
1133 ret = BT_COMPONENT_STATUS_ERROR;
1134 goto end;
1135 }
3228cc1d 1136 ret = print_field(pretty, field, print_names, NULL, 0);
6a18b281
MD
1137end:
1138 bt_put(field);
1139 return ret;
1140}
1141
1142static
3228cc1d 1143enum bt_component_status print_sequence(struct pretty_component *pretty,
6a18b281
MD
1144 struct bt_ctf_field *seq, bool print_names)
1145{
1146 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
1147 struct bt_ctf_field_type *seq_type = NULL, *field_type = NULL;
1148 struct bt_ctf_field *length_field = NULL;
1487a16a 1149 enum bt_ctf_field_type_id type_id;
6a18b281
MD
1150 uint64_t len;
1151 uint64_t i;
1152 bool is_string = false;
1153
1154 seq_type = bt_ctf_field_get_type(seq);
1155 if (!seq_type) {
1156 ret = BT_COMPONENT_STATUS_ERROR;
1157 goto end;
1158 }
1159 length_field = bt_ctf_field_sequence_get_length(seq);
1160 if (!length_field) {
1161 ret = BT_COMPONENT_STATUS_ERROR;
1162 goto end;
1163 }
1164 if (bt_ctf_field_unsigned_integer_get_value(length_field, &len) < 0) {
1165 ret = BT_COMPONENT_STATUS_ERROR;
1166 goto end;
1167 }
1168 field_type = bt_ctf_field_type_sequence_get_element_type(seq_type);
1169 if (!field_type) {
1170 ret = BT_COMPONENT_STATUS_ERROR;
1171 goto end;
1172 }
1173 type_id = bt_ctf_field_type_get_type_id(field_type);
1487a16a 1174 if (type_id == BT_CTF_FIELD_TYPE_ID_INTEGER) {
6a18b281
MD
1175 enum bt_ctf_string_encoding encoding;
1176
1177 encoding = bt_ctf_field_type_integer_get_encoding(field_type);
1178 if (encoding == BT_CTF_STRING_ENCODING_UTF8
1179 || encoding == BT_CTF_STRING_ENCODING_ASCII) {
1180 int integer_len, integer_alignment;
1181
1182 integer_len = bt_ctf_field_type_integer_get_size(field_type);
1183 if (integer_len < 0) {
1184 ret = BT_COMPONENT_STATUS_ERROR;
1185 goto end;
1186 }
1187 integer_alignment = bt_ctf_field_type_get_alignment(field_type);
1188 if (integer_alignment < 0) {
1189 ret = BT_COMPONENT_STATUS_ERROR;
1190 goto end;
1191 }
1192 if (integer_len == CHAR_BIT
1193 && integer_alignment == CHAR_BIT) {
1194 is_string = true;
1195 }
1196 }
1197 }
1198
1199 if (is_string) {
5280f742 1200 g_string_assign(pretty->tmp_string, "");
6a18b281 1201 } else {
5280f742 1202 g_string_append(pretty->string, "[");
6a18b281
MD
1203 }
1204
3228cc1d 1205 pretty->depth++;
6a18b281 1206 for (i = 0; i < len; i++) {
3228cc1d 1207 ret = print_sequence_field(pretty, seq, i,
6a18b281
MD
1208 is_string, print_names);
1209 if (ret != BT_COMPONENT_STATUS_OK) {
1210 goto end;
1211 }
1212 }
3228cc1d 1213 pretty->depth--;
6a18b281
MD
1214
1215 if (is_string) {
3228cc1d 1216 if (pretty->use_colors) {
5280f742 1217 g_string_append(pretty->string, COLOR_STRING_VALUE);
ad96d936 1218 }
5280f742 1219 print_escape_string(pretty, pretty->tmp_string->str);
3228cc1d 1220 if (pretty->use_colors) {
5280f742 1221 g_string_append(pretty->string, COLOR_RST);
ad96d936 1222 }
6a18b281 1223 } else {
5280f742 1224 g_string_append(pretty->string, " ]");
6a18b281
MD
1225 }
1226end:
1227 bt_put(length_field);
1228 bt_put(field_type);
1229 bt_put(seq_type);
1230 return ret;
1231}
1232
1233static
3228cc1d 1234enum bt_component_status print_variant(struct pretty_component *pretty,
6a18b281
MD
1235 struct bt_ctf_field *variant, bool print_names)
1236{
1237 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
1238 struct bt_ctf_field *field = NULL;
1239
1240 field = bt_ctf_field_variant_get_current_field(variant);
1241 if (!field) {
1242 ret = BT_COMPONENT_STATUS_ERROR;
1243 goto end;
1244 }
5280f742 1245 g_string_append(pretty->string, "{ ");
3228cc1d 1246 pretty->depth++;
6a18b281 1247 if (print_names) {
e0f15669 1248 int iter_ret;
6a18b281
MD
1249 struct bt_ctf_field *tag_field = NULL;
1250 const char *tag_choice;
e0f15669 1251 struct bt_ctf_field_type_enumeration_mapping_iterator *iter;
6a18b281
MD
1252
1253 tag_field = bt_ctf_field_variant_get_tag(variant);
1254 if (!tag_field) {
1255 ret = BT_COMPONENT_STATUS_ERROR;
1256 goto end;
1257 }
e0f15669
JG
1258
1259 iter = bt_ctf_field_enumeration_get_mappings(tag_field);
1260 if (!iter) {
1261 bt_put(tag_field);
1262 ret = BT_COMPONENT_STATUS_ERROR;
1263 goto end;
1264 }
1265
1266 iter_ret =
8803be2a
JG
1267 bt_ctf_field_type_enumeration_mapping_iterator_get_signed(
1268 iter, &tag_choice, NULL, NULL);
e0f15669
JG
1269 if (iter_ret) {
1270 bt_put(iter);
6a18b281
MD
1271 bt_put(tag_field);
1272 ret = BT_COMPONENT_STATUS_ERROR;
1273 goto end;
1274 }
3228cc1d 1275 print_field_name_equal(pretty, rem_(tag_choice));
6a18b281 1276 bt_put(tag_field);
e0f15669 1277 bt_put(iter);
6a18b281 1278 }
3228cc1d 1279 ret = print_field(pretty, field, print_names, NULL, 0);
6a18b281
MD
1280 if (ret != BT_COMPONENT_STATUS_OK) {
1281 goto end;
1282 }
3228cc1d 1283 pretty->depth--;
5280f742 1284 g_string_append(pretty->string, " }");
6a18b281
MD
1285end:
1286 bt_put(field);
1287 return ret;
1288}
1289
1290static
3228cc1d 1291enum bt_component_status print_field(struct pretty_component *pretty,
2b4c4a7c
JD
1292 struct bt_ctf_field *field, bool print_names,
1293 GQuark *filter_fields, int filter_array_len)
6a18b281 1294{
1487a16a 1295 enum bt_ctf_field_type_id type_id;
6a18b281
MD
1296
1297 type_id = bt_ctf_field_get_type_id(field);
1298 switch (type_id) {
1299 case CTF_TYPE_INTEGER:
3228cc1d 1300 return print_integer(pretty, field);
6a18b281
MD
1301 case CTF_TYPE_FLOAT:
1302 {
1303 double v;
1304
1305 if (bt_ctf_field_floating_point_get_value(field, &v)) {
1306 return BT_COMPONENT_STATUS_ERROR;
1307 }
3228cc1d 1308 if (pretty->use_colors) {
5280f742 1309 g_string_append(pretty->string, COLOR_NUMBER_VALUE);
ad96d936 1310 }
5280f742 1311 g_string_append_printf(pretty->string, "%g", v);
3228cc1d 1312 if (pretty->use_colors) {
5280f742 1313 g_string_append(pretty->string, COLOR_RST);
ad96d936 1314 }
6a18b281
MD
1315 return BT_COMPONENT_STATUS_OK;
1316 }
1317 case CTF_TYPE_ENUM:
3228cc1d 1318 return print_enum(pretty, field);
6a18b281 1319 case CTF_TYPE_STRING:
d1f0e0e3
JG
1320 {
1321 const char *str;
1322
1323 str = bt_ctf_field_string_get_value(field);
1324 if (!str) {
1325 return BT_COMPONENT_STATUS_ERROR;
1326 }
1327
3228cc1d 1328 if (pretty->use_colors) {
5280f742 1329 g_string_append(pretty->string, COLOR_STRING_VALUE);
ad96d936 1330 }
d1f0e0e3 1331 print_escape_string(pretty, str);
3228cc1d 1332 if (pretty->use_colors) {
5280f742 1333 g_string_append(pretty->string, COLOR_RST);
ad96d936 1334 }
6a18b281 1335 return BT_COMPONENT_STATUS_OK;
d1f0e0e3 1336 }
6a18b281 1337 case CTF_TYPE_STRUCT:
3228cc1d 1338 return print_struct(pretty, field, print_names, filter_fields,
2b4c4a7c 1339 filter_array_len);
6a18b281 1340 case CTF_TYPE_VARIANT:
3228cc1d 1341 return print_variant(pretty, field, print_names);
6a18b281 1342 case CTF_TYPE_ARRAY:
3228cc1d 1343 return print_array(pretty, field, print_names);
6a18b281 1344 case CTF_TYPE_SEQUENCE:
3228cc1d 1345 return print_sequence(pretty, field, print_names);
6a18b281 1346 default:
5280f742 1347 // TODO: log instead
3228cc1d 1348 fprintf(pretty->err, "[error] Unknown type id: %d\n", (int) type_id);
6a18b281
MD
1349 return BT_COMPONENT_STATUS_ERROR;
1350 }
1351}
1352
1353static
3228cc1d 1354enum bt_component_status print_stream_packet_context(struct pretty_component *pretty,
6a18b281
MD
1355 struct bt_ctf_event *event)
1356{
1357 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
1358 struct bt_ctf_packet *packet = NULL;
1359 struct bt_ctf_field *main_field = NULL;
1360
1361 packet = bt_ctf_event_get_packet(event);
1362 if (!packet) {
1363 ret = BT_COMPONENT_STATUS_ERROR;
1364 goto end;
1365 }
1366 main_field = bt_ctf_packet_get_context(packet);
1367 if (!main_field) {
6a18b281
MD
1368 goto end;
1369 }
3228cc1d 1370 if (!pretty->start_line) {
5280f742 1371 g_string_append(pretty->string, ", ");
6e1bc0df 1372 }
3228cc1d
PP
1373 pretty->start_line = false;
1374 if (pretty->options.print_scope_field_names) {
1375 print_name_equal(pretty, "stream.packet.context");
6a18b281 1376 }
3228cc1d
PP
1377 ret = print_field(pretty, main_field,
1378 pretty->options.print_context_field_names,
2b4c4a7c
JD
1379 stream_packet_context_quarks,
1380 STREAM_PACKET_CONTEXT_QUARKS_LEN);
6a18b281
MD
1381end:
1382 bt_put(main_field);
1383 bt_put(packet);
1384 return ret;
1385}
1386
1387static
3228cc1d 1388enum bt_component_status print_event_header_raw(struct pretty_component *pretty,
6a18b281
MD
1389 struct bt_ctf_event *event)
1390{
1391 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
1392 struct bt_ctf_field *main_field = NULL;
1393
1394 main_field = bt_ctf_event_get_header(event);
1395 if (!main_field) {
6a18b281
MD
1396 goto end;
1397 }
3228cc1d 1398 if (!pretty->start_line) {
5280f742 1399 g_string_append(pretty->string, ", ");
6e1bc0df 1400 }
3228cc1d
PP
1401 pretty->start_line = false;
1402 if (pretty->options.print_scope_field_names) {
1403 print_name_equal(pretty, "stream.event.header");
6a18b281 1404 }
3228cc1d
PP
1405 ret = print_field(pretty, main_field,
1406 pretty->options.print_header_field_names, NULL, 0);
6a18b281
MD
1407end:
1408 bt_put(main_field);
1409 return ret;
1410}
1411
1412static
3228cc1d 1413enum bt_component_status print_stream_event_context(struct pretty_component *pretty,
6a18b281
MD
1414 struct bt_ctf_event *event)
1415{
1416 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
1417 struct bt_ctf_field *main_field = NULL;
1418
1419 main_field = bt_ctf_event_get_stream_event_context(event);
1420 if (!main_field) {
6a18b281
MD
1421 goto end;
1422 }
3228cc1d 1423 if (!pretty->start_line) {
5280f742 1424 g_string_append(pretty->string, ", ");
6e1bc0df 1425 }
3228cc1d
PP
1426 pretty->start_line = false;
1427 if (pretty->options.print_scope_field_names) {
1428 print_name_equal(pretty, "stream.event.context");
6a18b281 1429 }
3228cc1d
PP
1430 ret = print_field(pretty, main_field,
1431 pretty->options.print_context_field_names, NULL, 0);
6a18b281
MD
1432end:
1433 bt_put(main_field);
1434 return ret;
1435}
1436
1437static
3228cc1d 1438enum bt_component_status print_event_context(struct pretty_component *pretty,
6a18b281
MD
1439 struct bt_ctf_event *event)
1440{
1441 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
1442 struct bt_ctf_field *main_field = NULL;
1443
1444 main_field = bt_ctf_event_get_event_context(event);
1445 if (!main_field) {
6a18b281
MD
1446 goto end;
1447 }
3228cc1d 1448 if (!pretty->start_line) {
5280f742 1449 g_string_append(pretty->string, ", ");
6e1bc0df 1450 }
3228cc1d
PP
1451 pretty->start_line = false;
1452 if (pretty->options.print_scope_field_names) {
1453 print_name_equal(pretty, "event.context");
6a18b281 1454 }
3228cc1d
PP
1455 ret = print_field(pretty, main_field,
1456 pretty->options.print_context_field_names, NULL, 0);
6a18b281
MD
1457end:
1458 bt_put(main_field);
1459 return ret;
1460}
1461
1462static
3228cc1d 1463enum bt_component_status print_event_payload(struct pretty_component *pretty,
6a18b281
MD
1464 struct bt_ctf_event *event)
1465{
1466 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
1467 struct bt_ctf_field *main_field = NULL;
1468
9ac68eb1 1469 main_field = bt_ctf_event_get_event_payload(event);
6a18b281 1470 if (!main_field) {
6a18b281
MD
1471 goto end;
1472 }
3228cc1d 1473 if (!pretty->start_line) {
5280f742 1474 g_string_append(pretty->string, ", ");
6e1bc0df 1475 }
3228cc1d
PP
1476 pretty->start_line = false;
1477 if (pretty->options.print_scope_field_names) {
1478 print_name_equal(pretty, "event.fields");
6a18b281 1479 }
3228cc1d
PP
1480 ret = print_field(pretty, main_field,
1481 pretty->options.print_payload_field_names, NULL, 0);
6a18b281
MD
1482end:
1483 bt_put(main_field);
af9a82eb
JG
1484 return ret;
1485}
1486
da6febac
PP
1487static
1488int flush_buf(struct pretty_component *pretty)
1489{
1490 int ret = 0;
1491
1492 if (pretty->string->len == 0) {
1493 goto end;
1494 }
1495
1496 if (fwrite(pretty->string->str, pretty->string->len, 1, pretty->out) != 1) {
1497 ret = -1;
1498 }
1499
1500end:
1501 return ret;
1502}
1503
af9a82eb 1504BT_HIDDEN
3228cc1d 1505enum bt_component_status pretty_print_event(struct pretty_component *pretty,
d9f65f09 1506 struct bt_notification *event_notif)
af9a82eb
JG
1507{
1508 enum bt_component_status ret;
d9f65f09
PP
1509 struct bt_ctf_event *event =
1510 bt_notification_event_get_event(event_notif);
1511 struct bt_clock_class_priority_map *cc_prio_map =
1512 bt_notification_event_get_clock_class_priority_map(event_notif);
af9a82eb 1513
d9f65f09
PP
1514 assert(event);
1515 assert(cc_prio_map);
3228cc1d 1516 pretty->start_line = true;
5280f742 1517 g_string_assign(pretty->string, "");
d9f65f09 1518 ret = print_event_header(pretty, event, cc_prio_map);
af9a82eb
JG
1519 if (ret != BT_COMPONENT_STATUS_OK) {
1520 goto end;
1521 }
6a18b281 1522
3228cc1d 1523 ret = print_stream_packet_context(pretty, event);
6a18b281
MD
1524 if (ret != BT_COMPONENT_STATUS_OK) {
1525 goto end;
1526 }
6a18b281 1527
3228cc1d
PP
1528 if (pretty->options.verbose) {
1529 ret = print_event_header_raw(pretty, event);
60535549
JD
1530 if (ret != BT_COMPONENT_STATUS_OK) {
1531 goto end;
1532 }
6a18b281 1533 }
6a18b281 1534
3228cc1d 1535 ret = print_stream_event_context(pretty, event);
6a18b281
MD
1536 if (ret != BT_COMPONENT_STATUS_OK) {
1537 goto end;
1538 }
6a18b281 1539
3228cc1d 1540 ret = print_event_context(pretty, event);
6a18b281
MD
1541 if (ret != BT_COMPONENT_STATUS_OK) {
1542 goto end;
1543 }
6a18b281 1544
3228cc1d 1545 ret = print_event_payload(pretty, event);
6a18b281
MD
1546 if (ret != BT_COMPONENT_STATUS_OK) {
1547 goto end;
1548 }
af9a82eb 1549
5280f742 1550 g_string_append_c(pretty->string, '\n');
da6febac 1551 if (flush_buf(pretty)) {
5280f742
PP
1552 ret = BT_COMPONENT_STATUS_ERROR;
1553 goto end;
1554 }
1555
af9a82eb 1556end:
d9f65f09
PP
1557 bt_put(event);
1558 bt_put(cc_prio_map);
af9a82eb
JG
1559 return ret;
1560}
da6febac
PP
1561
1562BT_HIDDEN
1563enum bt_component_status pretty_print_discarded_elements(
1564 struct pretty_component *pretty,
1565 struct bt_notification *notif)
1566{
1567 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
1568 struct bt_ctf_stream *stream = NULL;
1569 struct bt_ctf_stream_class *stream_class = NULL;
1570 struct bt_ctf_trace *trace = NULL;
1571 const char *stream_name;
1572 const char *trace_name;
1573 const unsigned char *trace_uuid;
1574 int64_t stream_class_id;
1575 int64_t stream_id;
1576 bool is_discarded_events;
4a111761 1577 int64_t count;
0c1887c9 1578 struct bt_ctf_clock_value *clock_value = NULL;
da6febac
PP
1579
1580 /* Stream name */
1581 switch (bt_notification_get_type(notif)) {
1582 case BT_NOTIFICATION_TYPE_DISCARDED_EVENTS:
1583 stream = bt_notification_discarded_events_get_stream(notif);
4a111761 1584 count = bt_notification_discarded_events_get_count(notif);
da6febac
PP
1585 is_discarded_events = true;
1586 break;
1587 case BT_NOTIFICATION_TYPE_DISCARDED_PACKETS:
1588 stream = bt_notification_discarded_packets_get_stream(notif);
4a111761 1589 count = bt_notification_discarded_packets_get_count(notif);
da6febac
PP
1590 is_discarded_events = false;
1591 break;
1592 default:
1593 abort();
1594 }
1595
1596 assert(stream);
1597 stream_name = bt_ctf_stream_get_name(stream);
1598
1599 /* Stream class ID */
1600 stream_class = bt_ctf_stream_get_class(stream);
1601 assert(stream_class);
1602 stream_class_id = bt_ctf_stream_class_get_id(stream_class);
1603
1604 /* Stream ID */
1605 stream_id = bt_ctf_stream_get_id(stream);
1606
1607 /* Trace path */
1608 trace = bt_ctf_stream_class_get_trace(stream_class);
1609 assert(trace);
1610 trace_name = bt_ctf_trace_get_name(trace);
1611 if (!trace_name) {
1612 trace_name = "(unknown)";
1613 }
1614
1615 /* Trace UUID */
1616 trace_uuid = bt_ctf_trace_get_uuid(trace);
1617
1618 /*
1619 * Print to standard error stream to remain backward compatible
1620 * with Babeltrace 1.
1621 */
1622 fprintf(stderr,
4a111761 1623 "%s%sWARNING%s%s: Tracer discarded %" PRId64 " %s%s between [",
da6febac
PP
1624 bt_common_color_fg_yellow(),
1625 bt_common_color_bold(),
1626 bt_common_color_reset(),
1627 bt_common_color_fg_yellow(),
4a111761
PP
1628 count, is_discarded_events ? "event" : "packet",
1629 count == 1 ? "" : "s");
da6febac 1630 g_string_assign(pretty->string, "");
0c1887c9 1631 clock_value = is_discarded_events ?
da6febac 1632 bt_notification_discarded_events_get_begin_clock_value(notif) :
0c1887c9
PP
1633 bt_notification_discarded_packets_get_begin_clock_value(notif);
1634 print_timestamp_wall(pretty, clock_value);
1635 BT_PUT(clock_value);
da6febac
PP
1636 fprintf(stderr, "%s] and [", pretty->string->str);
1637 g_string_assign(pretty->string, "");
0c1887c9 1638 clock_value = is_discarded_events ?
da6febac 1639 bt_notification_discarded_events_get_end_clock_value(notif) :
0c1887c9
PP
1640 bt_notification_discarded_packets_get_end_clock_value(notif);
1641 print_timestamp_wall(pretty, clock_value);
1642 BT_PUT(clock_value);
da6febac
PP
1643 fprintf(stderr, "%s] in trace \"%s\" ",
1644 pretty->string->str, trace_name);
1645
1646 if (trace_uuid) {
1647 fprintf(stderr,
1648 "(UUID: %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x) ",
1649 trace_uuid[0],
1650 trace_uuid[1],
1651 trace_uuid[2],
1652 trace_uuid[3],
1653 trace_uuid[4],
1654 trace_uuid[5],
1655 trace_uuid[6],
1656 trace_uuid[7],
1657 trace_uuid[8],
1658 trace_uuid[9],
1659 trace_uuid[10],
1660 trace_uuid[11],
1661 trace_uuid[12],
1662 trace_uuid[13],
1663 trace_uuid[14],
1664 trace_uuid[15]);
1665 } else {
1666 fprintf(stderr, "(no UUID) ");
1667 }
1668
1669 fprintf(stderr, "within stream \"%s\" (stream class ID: %" PRId64 ", ",
1670 stream_name, stream_class_id);
1671
1672 if (stream_id >= 0) {
1673 fprintf(stderr, "stream ID: %" PRId64, stream_id);
1674 } else {
1675 fprintf(stderr, "no stream ID");
1676 }
1677
1678 fprintf(stderr, ").%s\n", bt_common_color_reset());
1679 bt_put(stream);
1680 bt_put(stream_class);
1681 bt_put(trace);
0c1887c9 1682 bt_put(clock_value);
da6febac
PP
1683 return ret;
1684}
This page took 0.115977 seconds and 4 git commands to generate.