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