Fix: handle unknown enum mapping
[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>
08899d39
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
08899d39 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
08899d39 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,
08899d39 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
18adbd19 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");
18adbd19 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 {
08899d39
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) {
cf76ce92
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
cf76ce92 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 }
cf76ce92
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) {
cf76ce92 548 const char *uri_str;
c3c30b08 549
cf76ce92 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
cf76ce92 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:
d2bd5ad3 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 }
83ef3205 852 g_string_append(pretty->string, "( ");
96e8f959 853 if (!iter) {
83ef3205
MD
854 if (pretty->use_colors) {
855 g_string_append(pretty->string, COLOR_UNKNOWN);
856 }
857 g_string_append(pretty->string, "<unknown>");
858 if (pretty->use_colors) {
859 g_string_append(pretty->string, COLOR_RST);
860 }
861 goto skip_loop;
96e8f959 862 }
96e8f959
MD
863 for (;;) {
864 const char *mapping_name;
865
866 if (bt_ctf_field_type_enumeration_mapping_iterator_get_signed(
867 iter, &mapping_name, NULL, NULL) < 0) {
868 ret = BT_COMPONENT_STATUS_ERROR;
869 goto end;
870 }
871 if (nr_mappings++)
5280f742 872 g_string_append(pretty->string, ", ");
3228cc1d 873 if (pretty->use_colors) {
5280f742 874 g_string_append(pretty->string, COLOR_ENUM_MAPPING_NAME);
ad96d936 875 }
3228cc1d
PP
876 print_escape_string(pretty, mapping_name);
877 if (pretty->use_colors) {
5280f742 878 g_string_append(pretty->string, COLOR_RST);
ad96d936 879 }
96e8f959
MD
880 if (bt_ctf_field_type_enumeration_mapping_iterator_next(iter) < 0) {
881 break;
882 }
883 }
83ef3205 884skip_loop:
5280f742 885 g_string_append(pretty->string, " : container = ");
3228cc1d 886 ret = print_integer(pretty, container_field);
6a18b281
MD
887 if (ret != BT_COMPONENT_STATUS_OK) {
888 goto end;
889 }
5280f742 890 g_string_append(pretty->string, " )");
6a18b281 891end:
96e8f959
MD
892 bt_put(iter);
893 bt_put(container_field_type);
6a18b281 894 bt_put(container_field);
96e8f959 895 bt_put(enumeration_field_type);
6a18b281
MD
896 return ret;
897}
898
2b4c4a7c 899static
3228cc1d 900int filter_field_name(struct pretty_component *pretty, const char *field_name,
2b4c4a7c
JD
901 GQuark *filter_fields, int filter_array_len)
902{
903 int i;
904 GQuark field_quark = g_quark_try_string(field_name);
905
3228cc1d 906 if (!field_quark || pretty->options.verbose) {
2b4c4a7c
JD
907 return 1;
908 }
909
910 for (i = 0; i < filter_array_len; i++) {
911 if (field_quark == filter_fields[i]) {
912 return 0;
913 }
914 }
915 return 1;
916}
917
6a18b281 918static
3228cc1d 919enum bt_component_status print_struct_field(struct pretty_component *pretty,
6a18b281
MD
920 struct bt_ctf_field *_struct,
921 struct bt_ctf_field_type *struct_type,
2b4c4a7c
JD
922 int i, bool print_names, int *nr_printed_fields,
923 GQuark *filter_fields, int filter_array_len)
6a18b281
MD
924{
925 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
926 const char *field_name;
927 struct bt_ctf_field *field = NULL;
928 struct bt_ctf_field_type *field_type = NULL;;
929
930 field = bt_ctf_field_structure_get_field_by_index(_struct, i);
931 if (!field) {
932 ret = BT_COMPONENT_STATUS_ERROR;
933 goto end;
934 }
935 if (bt_ctf_field_type_structure_get_field(struct_type,
936 &field_name, &field_type, i) < 0) {
937 ret = BT_COMPONENT_STATUS_ERROR;
938 goto end;
939 }
940
3228cc1d 941 if (filter_fields && !filter_field_name(pretty, field_name,
2b4c4a7c
JD
942 filter_fields, filter_array_len)) {
943 ret = BT_COMPONENT_STATUS_OK;
944 goto end;
945 }
946
947 if (*nr_printed_fields > 0) {
5280f742 948 g_string_append(pretty->string, ", ");
6a18b281 949 } else {
5280f742 950 g_string_append(pretty->string, " ");
6a18b281
MD
951 }
952 if (print_names) {
3228cc1d 953 print_field_name_equal(pretty, rem_(field_name));
6a18b281 954 }
3228cc1d 955 ret = print_field(pretty, field, print_names, NULL, 0);
2b4c4a7c 956 *nr_printed_fields += 1;
6a18b281
MD
957end:
958 bt_put(field_type);
959 bt_put(field);
960 return ret;
961}
962
963static
3228cc1d 964enum bt_component_status print_struct(struct pretty_component *pretty,
2b4c4a7c
JD
965 struct bt_ctf_field *_struct, bool print_names,
966 GQuark *filter_fields, int filter_array_len)
6a18b281
MD
967{
968 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
969 struct bt_ctf_field_type *struct_type = NULL;
2b4c4a7c 970 int nr_fields, i, nr_printed_fields;
6a18b281
MD
971
972 struct_type = bt_ctf_field_get_type(_struct);
973 if (!struct_type) {
974 ret = BT_COMPONENT_STATUS_ERROR;
975 goto end;
976 }
977 nr_fields = bt_ctf_field_type_structure_get_field_count(struct_type);
978 if (nr_fields < 0) {
979 ret = BT_COMPONENT_STATUS_ERROR;
980 goto end;
981 }
5280f742 982 g_string_append(pretty->string, "{");
3228cc1d 983 pretty->depth++;
2b4c4a7c 984 nr_printed_fields = 0;
6a18b281 985 for (i = 0; i < nr_fields; i++) {
3228cc1d 986 ret = print_struct_field(pretty, _struct, struct_type, i,
2b4c4a7c
JD
987 print_names, &nr_printed_fields, filter_fields,
988 filter_array_len);
6a18b281
MD
989 if (ret != BT_COMPONENT_STATUS_OK) {
990 goto end;
991 }
992 }
3228cc1d 993 pretty->depth--;
5280f742 994 g_string_append(pretty->string, " }");
6a18b281
MD
995end:
996 bt_put(struct_type);
997 return ret;
998}
999
1000static
3228cc1d 1001enum bt_component_status print_array_field(struct pretty_component *pretty,
6a18b281
MD
1002 struct bt_ctf_field *array, uint64_t i,
1003 bool is_string, bool print_names)
1004{
1005 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
1006 struct bt_ctf_field *field = NULL;
1007
1008 if (!is_string) {
1009 if (i != 0) {
5280f742 1010 g_string_append(pretty->string, ", ");
6a18b281 1011 } else {
5280f742 1012 g_string_append(pretty->string, " ");
6a18b281 1013 }
60535549 1014 if (print_names) {
5280f742 1015 g_string_append_printf(pretty->string, "[%" PRIu64 "] = ", i);
60535549 1016 }
6a18b281
MD
1017 }
1018 field = bt_ctf_field_array_get_field(array, i);
1019 if (!field) {
1020 ret = BT_COMPONENT_STATUS_ERROR;
1021 goto end;
1022 }
3228cc1d 1023 ret = print_field(pretty, field, print_names, NULL, 0);
6a18b281
MD
1024end:
1025 bt_put(field);
1026 return ret;
1027}
1028
1029static
3228cc1d 1030enum bt_component_status print_array(struct pretty_component *pretty,
6a18b281
MD
1031 struct bt_ctf_field *array, bool print_names)
1032{
1033 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
1034 struct bt_ctf_field_type *array_type = NULL, *field_type = NULL;
1487a16a 1035 enum bt_ctf_field_type_id type_id;
6a18b281
MD
1036 int64_t len;
1037 uint64_t i;
1038 bool is_string = false;
1039
1040 array_type = bt_ctf_field_get_type(array);
1041 if (!array_type) {
1042 ret = BT_COMPONENT_STATUS_ERROR;
1043 goto end;
1044 }
1045 field_type = bt_ctf_field_type_array_get_element_type(array_type);
1046 if (!field_type) {
1047 ret = BT_COMPONENT_STATUS_ERROR;
1048 goto end;
1049 }
1050 len = bt_ctf_field_type_array_get_length(array_type);
1051 if (len < 0) {
1052 ret = BT_COMPONENT_STATUS_ERROR;
1053 goto end;
1054 }
1055 type_id = bt_ctf_field_type_get_type_id(field_type);
1487a16a 1056 if (type_id == BT_CTF_FIELD_TYPE_ID_INTEGER) {
6a18b281
MD
1057 enum bt_ctf_string_encoding encoding;
1058
1059 encoding = bt_ctf_field_type_integer_get_encoding(field_type);
1060 if (encoding == BT_CTF_STRING_ENCODING_UTF8
1061 || encoding == BT_CTF_STRING_ENCODING_ASCII) {
1062 int integer_len, integer_alignment;
1063
1064 integer_len = bt_ctf_field_type_integer_get_size(field_type);
1065 if (integer_len < 0) {
1066 return BT_COMPONENT_STATUS_ERROR;
1067 }
1068 integer_alignment = bt_ctf_field_type_get_alignment(field_type);
1069 if (integer_alignment < 0) {
1070 return BT_COMPONENT_STATUS_ERROR;
1071 }
1072 if (integer_len == CHAR_BIT
1073 && integer_alignment == CHAR_BIT) {
1074 is_string = true;
1075 }
1076 }
1077 }
1078
1079 if (is_string) {
5280f742 1080 g_string_assign(pretty->tmp_string, "");
6a18b281 1081 } else {
5280f742 1082 g_string_append(pretty->string, "[");
6a18b281
MD
1083 }
1084
3228cc1d 1085 pretty->depth++;
6a18b281 1086 for (i = 0; i < len; i++) {
3228cc1d 1087 ret = print_array_field(pretty, array, i, is_string, print_names);
6a18b281
MD
1088 if (ret != BT_COMPONENT_STATUS_OK) {
1089 goto end;
1090 }
1091 }
3228cc1d 1092 pretty->depth--;
6a18b281
MD
1093
1094 if (is_string) {
3228cc1d 1095 if (pretty->use_colors) {
5280f742 1096 g_string_append(pretty->string, COLOR_STRING_VALUE);
ad96d936 1097 }
5280f742 1098 print_escape_string(pretty, pretty->tmp_string->str);
3228cc1d 1099 if (pretty->use_colors) {
5280f742 1100 g_string_append(pretty->string, COLOR_RST);
ad96d936 1101 }
6a18b281 1102 } else {
5280f742 1103 g_string_append(pretty->string, " ]");
6a18b281
MD
1104 }
1105end:
1106 bt_put(field_type);
1107 bt_put(array_type);
1108 return ret;
1109}
1110
1111static
3228cc1d 1112enum bt_component_status print_sequence_field(struct pretty_component *pretty,
6a18b281
MD
1113 struct bt_ctf_field *seq, uint64_t i,
1114 bool is_string, bool print_names)
1115{
1116 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
1117 struct bt_ctf_field *field = NULL;
1118
1119 if (!is_string) {
1120 if (i != 0) {
5280f742 1121 g_string_append(pretty->string, ", ");
6a18b281 1122 } else {
5280f742 1123 g_string_append(pretty->string, " ");
6a18b281 1124 }
60535549 1125 if (print_names) {
5280f742 1126 g_string_append_printf(pretty->string, "[%" PRIu64 "] = ", i);
60535549 1127 }
6a18b281
MD
1128 }
1129 field = bt_ctf_field_sequence_get_field(seq, i);
1130 if (!field) {
1131 ret = BT_COMPONENT_STATUS_ERROR;
1132 goto end;
1133 }
3228cc1d 1134 ret = print_field(pretty, field, print_names, NULL, 0);
6a18b281
MD
1135end:
1136 bt_put(field);
1137 return ret;
1138}
1139
1140static
3228cc1d 1141enum bt_component_status print_sequence(struct pretty_component *pretty,
6a18b281
MD
1142 struct bt_ctf_field *seq, bool print_names)
1143{
1144 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
1145 struct bt_ctf_field_type *seq_type = NULL, *field_type = NULL;
1146 struct bt_ctf_field *length_field = NULL;
1487a16a 1147 enum bt_ctf_field_type_id type_id;
6a18b281
MD
1148 uint64_t len;
1149 uint64_t i;
1150 bool is_string = false;
1151
1152 seq_type = bt_ctf_field_get_type(seq);
1153 if (!seq_type) {
1154 ret = BT_COMPONENT_STATUS_ERROR;
1155 goto end;
1156 }
1157 length_field = bt_ctf_field_sequence_get_length(seq);
1158 if (!length_field) {
1159 ret = BT_COMPONENT_STATUS_ERROR;
1160 goto end;
1161 }
1162 if (bt_ctf_field_unsigned_integer_get_value(length_field, &len) < 0) {
1163 ret = BT_COMPONENT_STATUS_ERROR;
1164 goto end;
1165 }
1166 field_type = bt_ctf_field_type_sequence_get_element_type(seq_type);
1167 if (!field_type) {
1168 ret = BT_COMPONENT_STATUS_ERROR;
1169 goto end;
1170 }
1171 type_id = bt_ctf_field_type_get_type_id(field_type);
1487a16a 1172 if (type_id == BT_CTF_FIELD_TYPE_ID_INTEGER) {
6a18b281
MD
1173 enum bt_ctf_string_encoding encoding;
1174
1175 encoding = bt_ctf_field_type_integer_get_encoding(field_type);
1176 if (encoding == BT_CTF_STRING_ENCODING_UTF8
1177 || encoding == BT_CTF_STRING_ENCODING_ASCII) {
1178 int integer_len, integer_alignment;
1179
1180 integer_len = bt_ctf_field_type_integer_get_size(field_type);
1181 if (integer_len < 0) {
1182 ret = BT_COMPONENT_STATUS_ERROR;
1183 goto end;
1184 }
1185 integer_alignment = bt_ctf_field_type_get_alignment(field_type);
1186 if (integer_alignment < 0) {
1187 ret = BT_COMPONENT_STATUS_ERROR;
1188 goto end;
1189 }
1190 if (integer_len == CHAR_BIT
1191 && integer_alignment == CHAR_BIT) {
1192 is_string = true;
1193 }
1194 }
1195 }
1196
1197 if (is_string) {
5280f742 1198 g_string_assign(pretty->tmp_string, "");
6a18b281 1199 } else {
5280f742 1200 g_string_append(pretty->string, "[");
6a18b281
MD
1201 }
1202
3228cc1d 1203 pretty->depth++;
6a18b281 1204 for (i = 0; i < len; i++) {
3228cc1d 1205 ret = print_sequence_field(pretty, seq, i,
6a18b281
MD
1206 is_string, print_names);
1207 if (ret != BT_COMPONENT_STATUS_OK) {
1208 goto end;
1209 }
1210 }
3228cc1d 1211 pretty->depth--;
6a18b281
MD
1212
1213 if (is_string) {
3228cc1d 1214 if (pretty->use_colors) {
5280f742 1215 g_string_append(pretty->string, COLOR_STRING_VALUE);
ad96d936 1216 }
5280f742 1217 print_escape_string(pretty, pretty->tmp_string->str);
3228cc1d 1218 if (pretty->use_colors) {
5280f742 1219 g_string_append(pretty->string, COLOR_RST);
ad96d936 1220 }
6a18b281 1221 } else {
5280f742 1222 g_string_append(pretty->string, " ]");
6a18b281
MD
1223 }
1224end:
1225 bt_put(length_field);
1226 bt_put(field_type);
1227 bt_put(seq_type);
1228 return ret;
1229}
1230
1231static
3228cc1d 1232enum bt_component_status print_variant(struct pretty_component *pretty,
6a18b281
MD
1233 struct bt_ctf_field *variant, bool print_names)
1234{
1235 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
1236 struct bt_ctf_field *field = NULL;
1237
1238 field = bt_ctf_field_variant_get_current_field(variant);
1239 if (!field) {
1240 ret = BT_COMPONENT_STATUS_ERROR;
1241 goto end;
1242 }
5280f742 1243 g_string_append(pretty->string, "{ ");
3228cc1d 1244 pretty->depth++;
6a18b281 1245 if (print_names) {
e0f15669 1246 int iter_ret;
6a18b281
MD
1247 struct bt_ctf_field *tag_field = NULL;
1248 const char *tag_choice;
e0f15669 1249 struct bt_ctf_field_type_enumeration_mapping_iterator *iter;
6a18b281
MD
1250
1251 tag_field = bt_ctf_field_variant_get_tag(variant);
1252 if (!tag_field) {
1253 ret = BT_COMPONENT_STATUS_ERROR;
1254 goto end;
1255 }
e0f15669
JG
1256
1257 iter = bt_ctf_field_enumeration_get_mappings(tag_field);
1258 if (!iter) {
1259 bt_put(tag_field);
1260 ret = BT_COMPONENT_STATUS_ERROR;
1261 goto end;
1262 }
1263
1264 iter_ret =
8803be2a
JG
1265 bt_ctf_field_type_enumeration_mapping_iterator_get_signed(
1266 iter, &tag_choice, NULL, NULL);
e0f15669
JG
1267 if (iter_ret) {
1268 bt_put(iter);
6a18b281
MD
1269 bt_put(tag_field);
1270 ret = BT_COMPONENT_STATUS_ERROR;
1271 goto end;
1272 }
3228cc1d 1273 print_field_name_equal(pretty, rem_(tag_choice));
6a18b281 1274 bt_put(tag_field);
e0f15669 1275 bt_put(iter);
6a18b281 1276 }
3228cc1d 1277 ret = print_field(pretty, field, print_names, NULL, 0);
6a18b281
MD
1278 if (ret != BT_COMPONENT_STATUS_OK) {
1279 goto end;
1280 }
3228cc1d 1281 pretty->depth--;
5280f742 1282 g_string_append(pretty->string, " }");
6a18b281
MD
1283end:
1284 bt_put(field);
1285 return ret;
1286}
1287
1288static
3228cc1d 1289enum bt_component_status print_field(struct pretty_component *pretty,
2b4c4a7c
JD
1290 struct bt_ctf_field *field, bool print_names,
1291 GQuark *filter_fields, int filter_array_len)
6a18b281 1292{
1487a16a 1293 enum bt_ctf_field_type_id type_id;
6a18b281
MD
1294
1295 type_id = bt_ctf_field_get_type_id(field);
1296 switch (type_id) {
1297 case CTF_TYPE_INTEGER:
3228cc1d 1298 return print_integer(pretty, field);
6a18b281
MD
1299 case CTF_TYPE_FLOAT:
1300 {
1301 double v;
1302
1303 if (bt_ctf_field_floating_point_get_value(field, &v)) {
1304 return BT_COMPONENT_STATUS_ERROR;
1305 }
3228cc1d 1306 if (pretty->use_colors) {
5280f742 1307 g_string_append(pretty->string, COLOR_NUMBER_VALUE);
ad96d936 1308 }
5280f742 1309 g_string_append_printf(pretty->string, "%g", v);
3228cc1d 1310 if (pretty->use_colors) {
5280f742 1311 g_string_append(pretty->string, COLOR_RST);
ad96d936 1312 }
6a18b281
MD
1313 return BT_COMPONENT_STATUS_OK;
1314 }
1315 case CTF_TYPE_ENUM:
3228cc1d 1316 return print_enum(pretty, field);
6a18b281 1317 case CTF_TYPE_STRING:
95a518bf
JG
1318 {
1319 const char *str;
1320
1321 str = bt_ctf_field_string_get_value(field);
1322 if (!str) {
1323 return BT_COMPONENT_STATUS_ERROR;
1324 }
1325
3228cc1d 1326 if (pretty->use_colors) {
5280f742 1327 g_string_append(pretty->string, COLOR_STRING_VALUE);
ad96d936 1328 }
95a518bf 1329 print_escape_string(pretty, str);
3228cc1d 1330 if (pretty->use_colors) {
5280f742 1331 g_string_append(pretty->string, COLOR_RST);
ad96d936 1332 }
6a18b281 1333 return BT_COMPONENT_STATUS_OK;
95a518bf 1334 }
6a18b281 1335 case CTF_TYPE_STRUCT:
3228cc1d 1336 return print_struct(pretty, field, print_names, filter_fields,
2b4c4a7c 1337 filter_array_len);
6a18b281 1338 case CTF_TYPE_VARIANT:
3228cc1d 1339 return print_variant(pretty, field, print_names);
6a18b281 1340 case CTF_TYPE_ARRAY:
3228cc1d 1341 return print_array(pretty, field, print_names);
6a18b281 1342 case CTF_TYPE_SEQUENCE:
3228cc1d 1343 return print_sequence(pretty, field, print_names);
6a18b281 1344 default:
5280f742 1345 // TODO: log instead
3228cc1d 1346 fprintf(pretty->err, "[error] Unknown type id: %d\n", (int) type_id);
6a18b281
MD
1347 return BT_COMPONENT_STATUS_ERROR;
1348 }
1349}
1350
1351static
3228cc1d 1352enum bt_component_status print_stream_packet_context(struct pretty_component *pretty,
6a18b281
MD
1353 struct bt_ctf_event *event)
1354{
1355 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
1356 struct bt_ctf_packet *packet = NULL;
1357 struct bt_ctf_field *main_field = NULL;
1358
1359 packet = bt_ctf_event_get_packet(event);
1360 if (!packet) {
1361 ret = BT_COMPONENT_STATUS_ERROR;
1362 goto end;
1363 }
1364 main_field = bt_ctf_packet_get_context(packet);
1365 if (!main_field) {
6a18b281
MD
1366 goto end;
1367 }
3228cc1d 1368 if (!pretty->start_line) {
5280f742 1369 g_string_append(pretty->string, ", ");
6e1bc0df 1370 }
3228cc1d
PP
1371 pretty->start_line = false;
1372 if (pretty->options.print_scope_field_names) {
1373 print_name_equal(pretty, "stream.packet.context");
6a18b281 1374 }
3228cc1d
PP
1375 ret = print_field(pretty, main_field,
1376 pretty->options.print_context_field_names,
2b4c4a7c
JD
1377 stream_packet_context_quarks,
1378 STREAM_PACKET_CONTEXT_QUARKS_LEN);
6a18b281
MD
1379end:
1380 bt_put(main_field);
1381 bt_put(packet);
1382 return ret;
1383}
1384
1385static
3228cc1d 1386enum bt_component_status print_event_header_raw(struct pretty_component *pretty,
6a18b281
MD
1387 struct bt_ctf_event *event)
1388{
1389 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
1390 struct bt_ctf_field *main_field = NULL;
1391
1392 main_field = bt_ctf_event_get_header(event);
1393 if (!main_field) {
6a18b281
MD
1394 goto end;
1395 }
3228cc1d 1396 if (!pretty->start_line) {
5280f742 1397 g_string_append(pretty->string, ", ");
6e1bc0df 1398 }
3228cc1d
PP
1399 pretty->start_line = false;
1400 if (pretty->options.print_scope_field_names) {
1401 print_name_equal(pretty, "stream.event.header");
6a18b281 1402 }
3228cc1d
PP
1403 ret = print_field(pretty, main_field,
1404 pretty->options.print_header_field_names, NULL, 0);
6a18b281
MD
1405end:
1406 bt_put(main_field);
1407 return ret;
1408}
1409
1410static
3228cc1d 1411enum bt_component_status print_stream_event_context(struct pretty_component *pretty,
6a18b281
MD
1412 struct bt_ctf_event *event)
1413{
1414 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
1415 struct bt_ctf_field *main_field = NULL;
1416
1417 main_field = bt_ctf_event_get_stream_event_context(event);
1418 if (!main_field) {
6a18b281
MD
1419 goto end;
1420 }
3228cc1d 1421 if (!pretty->start_line) {
5280f742 1422 g_string_append(pretty->string, ", ");
6e1bc0df 1423 }
3228cc1d
PP
1424 pretty->start_line = false;
1425 if (pretty->options.print_scope_field_names) {
1426 print_name_equal(pretty, "stream.event.context");
6a18b281 1427 }
3228cc1d
PP
1428 ret = print_field(pretty, main_field,
1429 pretty->options.print_context_field_names, NULL, 0);
6a18b281
MD
1430end:
1431 bt_put(main_field);
1432 return ret;
1433}
1434
1435static
3228cc1d 1436enum bt_component_status print_event_context(struct pretty_component *pretty,
6a18b281
MD
1437 struct bt_ctf_event *event)
1438{
1439 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
1440 struct bt_ctf_field *main_field = NULL;
1441
1442 main_field = bt_ctf_event_get_event_context(event);
1443 if (!main_field) {
6a18b281
MD
1444 goto end;
1445 }
3228cc1d 1446 if (!pretty->start_line) {
5280f742 1447 g_string_append(pretty->string, ", ");
6e1bc0df 1448 }
3228cc1d
PP
1449 pretty->start_line = false;
1450 if (pretty->options.print_scope_field_names) {
1451 print_name_equal(pretty, "event.context");
6a18b281 1452 }
3228cc1d
PP
1453 ret = print_field(pretty, main_field,
1454 pretty->options.print_context_field_names, NULL, 0);
6a18b281
MD
1455end:
1456 bt_put(main_field);
1457 return ret;
1458}
1459
1460static
3228cc1d 1461enum bt_component_status print_event_payload(struct pretty_component *pretty,
6a18b281
MD
1462 struct bt_ctf_event *event)
1463{
1464 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
1465 struct bt_ctf_field *main_field = NULL;
1466
9ac68eb1 1467 main_field = bt_ctf_event_get_event_payload(event);
6a18b281 1468 if (!main_field) {
6a18b281
MD
1469 goto end;
1470 }
3228cc1d 1471 if (!pretty->start_line) {
5280f742 1472 g_string_append(pretty->string, ", ");
6e1bc0df 1473 }
3228cc1d
PP
1474 pretty->start_line = false;
1475 if (pretty->options.print_scope_field_names) {
1476 print_name_equal(pretty, "event.fields");
6a18b281 1477 }
3228cc1d
PP
1478 ret = print_field(pretty, main_field,
1479 pretty->options.print_payload_field_names, NULL, 0);
6a18b281
MD
1480end:
1481 bt_put(main_field);
af9a82eb
JG
1482 return ret;
1483}
1484
08899d39
PP
1485static
1486int flush_buf(struct pretty_component *pretty)
1487{
1488 int ret = 0;
1489
1490 if (pretty->string->len == 0) {
1491 goto end;
1492 }
1493
1494 if (fwrite(pretty->string->str, pretty->string->len, 1, pretty->out) != 1) {
1495 ret = -1;
1496 }
1497
1498end:
1499 return ret;
1500}
1501
af9a82eb 1502BT_HIDDEN
3228cc1d 1503enum bt_component_status pretty_print_event(struct pretty_component *pretty,
d9f65f09 1504 struct bt_notification *event_notif)
af9a82eb
JG
1505{
1506 enum bt_component_status ret;
d9f65f09
PP
1507 struct bt_ctf_event *event =
1508 bt_notification_event_get_event(event_notif);
1509 struct bt_clock_class_priority_map *cc_prio_map =
1510 bt_notification_event_get_clock_class_priority_map(event_notif);
af9a82eb 1511
d9f65f09
PP
1512 assert(event);
1513 assert(cc_prio_map);
3228cc1d 1514 pretty->start_line = true;
5280f742 1515 g_string_assign(pretty->string, "");
d9f65f09 1516 ret = print_event_header(pretty, event, cc_prio_map);
af9a82eb
JG
1517 if (ret != BT_COMPONENT_STATUS_OK) {
1518 goto end;
1519 }
6a18b281 1520
3228cc1d 1521 ret = print_stream_packet_context(pretty, event);
6a18b281
MD
1522 if (ret != BT_COMPONENT_STATUS_OK) {
1523 goto end;
1524 }
6a18b281 1525
3228cc1d
PP
1526 if (pretty->options.verbose) {
1527 ret = print_event_header_raw(pretty, event);
60535549
JD
1528 if (ret != BT_COMPONENT_STATUS_OK) {
1529 goto end;
1530 }
6a18b281 1531 }
6a18b281 1532
3228cc1d 1533 ret = print_stream_event_context(pretty, event);
6a18b281
MD
1534 if (ret != BT_COMPONENT_STATUS_OK) {
1535 goto end;
1536 }
6a18b281 1537
3228cc1d 1538 ret = print_event_context(pretty, event);
6a18b281
MD
1539 if (ret != BT_COMPONENT_STATUS_OK) {
1540 goto end;
1541 }
6a18b281 1542
3228cc1d 1543 ret = print_event_payload(pretty, event);
6a18b281
MD
1544 if (ret != BT_COMPONENT_STATUS_OK) {
1545 goto end;
1546 }
af9a82eb 1547
5280f742 1548 g_string_append_c(pretty->string, '\n');
08899d39 1549 if (flush_buf(pretty)) {
5280f742
PP
1550 ret = BT_COMPONENT_STATUS_ERROR;
1551 goto end;
1552 }
1553
af9a82eb 1554end:
d9f65f09
PP
1555 bt_put(event);
1556 bt_put(cc_prio_map);
af9a82eb
JG
1557 return ret;
1558}
08899d39
PP
1559
1560BT_HIDDEN
1561enum bt_component_status pretty_print_discarded_elements(
1562 struct pretty_component *pretty,
1563 struct bt_notification *notif)
1564{
1565 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
1566 struct bt_ctf_stream *stream = NULL;
1567 struct bt_ctf_stream_class *stream_class = NULL;
1568 struct bt_ctf_trace *trace = NULL;
1569 const char *stream_name;
1570 const char *trace_name;
1571 const unsigned char *trace_uuid;
1572 int64_t stream_class_id;
1573 int64_t stream_id;
1574 bool is_discarded_events;
89bd87b6 1575 int64_t count;
db14aa44 1576 struct bt_ctf_clock_value *clock_value = NULL;
08899d39
PP
1577
1578 /* Stream name */
1579 switch (bt_notification_get_type(notif)) {
1580 case BT_NOTIFICATION_TYPE_DISCARDED_EVENTS:
1581 stream = bt_notification_discarded_events_get_stream(notif);
89bd87b6 1582 count = bt_notification_discarded_events_get_count(notif);
08899d39
PP
1583 is_discarded_events = true;
1584 break;
1585 case BT_NOTIFICATION_TYPE_DISCARDED_PACKETS:
1586 stream = bt_notification_discarded_packets_get_stream(notif);
89bd87b6 1587 count = bt_notification_discarded_packets_get_count(notif);
08899d39
PP
1588 is_discarded_events = false;
1589 break;
1590 default:
1591 abort();
1592 }
1593
1594 assert(stream);
1595 stream_name = bt_ctf_stream_get_name(stream);
1596
1597 /* Stream class ID */
1598 stream_class = bt_ctf_stream_get_class(stream);
1599 assert(stream_class);
1600 stream_class_id = bt_ctf_stream_class_get_id(stream_class);
1601
1602 /* Stream ID */
1603 stream_id = bt_ctf_stream_get_id(stream);
1604
1605 /* Trace path */
1606 trace = bt_ctf_stream_class_get_trace(stream_class);
1607 assert(trace);
1608 trace_name = bt_ctf_trace_get_name(trace);
1609 if (!trace_name) {
1610 trace_name = "(unknown)";
1611 }
1612
1613 /* Trace UUID */
1614 trace_uuid = bt_ctf_trace_get_uuid(trace);
1615
1616 /*
1617 * Print to standard error stream to remain backward compatible
1618 * with Babeltrace 1.
1619 */
1620 fprintf(stderr,
89bd87b6 1621 "%s%sWARNING%s%s: Tracer discarded %" PRId64 " %s%s between [",
08899d39
PP
1622 bt_common_color_fg_yellow(),
1623 bt_common_color_bold(),
1624 bt_common_color_reset(),
1625 bt_common_color_fg_yellow(),
89bd87b6
PP
1626 count, is_discarded_events ? "event" : "packet",
1627 count == 1 ? "" : "s");
08899d39 1628 g_string_assign(pretty->string, "");
db14aa44 1629 clock_value = is_discarded_events ?
08899d39 1630 bt_notification_discarded_events_get_begin_clock_value(notif) :
db14aa44
PP
1631 bt_notification_discarded_packets_get_begin_clock_value(notif);
1632 print_timestamp_wall(pretty, clock_value);
1633 BT_PUT(clock_value);
08899d39
PP
1634 fprintf(stderr, "%s] and [", pretty->string->str);
1635 g_string_assign(pretty->string, "");
db14aa44 1636 clock_value = is_discarded_events ?
08899d39 1637 bt_notification_discarded_events_get_end_clock_value(notif) :
db14aa44
PP
1638 bt_notification_discarded_packets_get_end_clock_value(notif);
1639 print_timestamp_wall(pretty, clock_value);
1640 BT_PUT(clock_value);
08899d39
PP
1641 fprintf(stderr, "%s] in trace \"%s\" ",
1642 pretty->string->str, trace_name);
1643
1644 if (trace_uuid) {
1645 fprintf(stderr,
1646 "(UUID: %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x) ",
1647 trace_uuid[0],
1648 trace_uuid[1],
1649 trace_uuid[2],
1650 trace_uuid[3],
1651 trace_uuid[4],
1652 trace_uuid[5],
1653 trace_uuid[6],
1654 trace_uuid[7],
1655 trace_uuid[8],
1656 trace_uuid[9],
1657 trace_uuid[10],
1658 trace_uuid[11],
1659 trace_uuid[12],
1660 trace_uuid[13],
1661 trace_uuid[14],
1662 trace_uuid[15]);
1663 } else {
1664 fprintf(stderr, "(no UUID) ");
1665 }
1666
1667 fprintf(stderr, "within stream \"%s\" (stream class ID: %" PRId64 ", ",
1668 stream_name, stream_class_id);
1669
1670 if (stream_id >= 0) {
1671 fprintf(stderr, "stream ID: %" PRId64, stream_id);
1672 } else {
1673 fprintf(stderr, "no stream ID");
1674 }
1675
1676 fprintf(stderr, ").%s\n", bt_common_color_reset());
1677 bt_put(stream);
1678 bt_put(stream_class);
1679 bt_put(trace);
db14aa44 1680 bt_put(clock_value);
08899d39
PP
1681 return ret;
1682}
This page took 0.11539 seconds and 4 git commands to generate.