Commit | Line | Data |
---|---|---|
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> | |
7 | * | |
8 | * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com> | |
9 | * | |
10 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
11 | * of this software and associated documentation files (the "Software"), to deal | |
12 | * in the Software without restriction, including without limitation the rights | |
13 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
14 | * copies of the Software, and to permit persons to whom the Software is | |
15 | * furnished to do so, subject to the following conditions: | |
16 | * | |
17 | * The above copyright notice and this permission notice shall be included in | |
18 | * all copies or substantial portions of the Software. | |
19 | * | |
20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
21 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
22 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
23 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
24 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
25 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
26 | * SOFTWARE. | |
27 | */ | |
28 | ||
29 | #include <babeltrace/ctf-ir/event.h> | |
30 | #include <babeltrace/ctf-ir/event-class.h> | |
6a18b281 | 31 | #include <babeltrace/ctf-ir/packet.h> |
af9a82eb JG |
32 | #include <babeltrace/ctf-ir/stream.h> |
33 | #include <babeltrace/ctf-ir/stream-class.h> | |
34 | #include <babeltrace/ctf-ir/clock.h> | |
6a18b281 MD |
35 | #include <babeltrace/ctf-ir/field-types.h> |
36 | #include <babeltrace/ctf-ir/fields.h> | |
37 | #include <babeltrace/bitfield.h> | |
38 | #include <inttypes.h> | |
af9a82eb JG |
39 | #include "text.h" |
40 | ||
6a18b281 MD |
41 | static inline |
42 | const char *rem_(const char *str) | |
43 | { | |
44 | if (str[0] == '_') | |
45 | return &str[1]; | |
46 | else | |
47 | return str; | |
48 | } | |
49 | ||
af9a82eb JG |
50 | struct timestamp { |
51 | int64_t real_timestamp; /* Relative to UNIX epoch. */ | |
52 | uint64_t clock_value; /* In cycles. */ | |
53 | }; | |
54 | ||
6a18b281 MD |
55 | static |
56 | enum bt_component_status print_field(struct text_component *text, | |
57 | struct bt_ctf_field *field, bool print_names); | |
58 | ||
af9a82eb JG |
59 | static |
60 | void print_timestamp_cycles(struct text_component *text, | |
61 | struct bt_ctf_clock *clock, | |
62 | struct bt_ctf_event *event) | |
63 | { | |
64 | fputs("00000000000000000000", text->out); | |
65 | } | |
66 | ||
67 | static | |
68 | void print_timestamp_wall(struct text_component *text, | |
69 | struct bt_ctf_clock *clock, | |
70 | struct bt_ctf_event *event) | |
71 | { | |
72 | fputs("??:??:??.?????????", text->out); | |
73 | } | |
74 | ||
75 | static | |
76 | enum bt_component_status get_event_timestamp(struct bt_ctf_event *event) | |
77 | { | |
78 | /* int ret; | |
79 | uint64_t value, frequency; | |
80 | int64_t offset_s, offset; | |
81 | */ | |
82 | return BT_COMPONENT_STATUS_OK; | |
83 | } | |
84 | ||
85 | static | |
86 | enum bt_component_status print_event_timestamp(struct text_component *text, | |
87 | struct bt_ctf_event *event) | |
88 | { | |
89 | bool print_names = text->options.print_header_field_names; | |
90 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
6a18b281 | 91 | struct bt_ctf_stream *stream = NULL; |
af9a82eb JG |
92 | struct bt_ctf_clock *clock = NULL; |
93 | FILE *out = text->out; | |
94 | FILE *err = text->err; | |
95 | uint64_t real_timestamp; | |
96 | ||
97 | stream = bt_ctf_event_get_stream(event); | |
98 | if (!stream) { | |
99 | ret = BT_COMPONENT_STATUS_ERROR; | |
100 | goto end; | |
101 | } | |
102 | ||
103 | clock = bt_ctf_event_get_clock(event); | |
104 | if (!clock) { | |
105 | /* Stream has no timestamp. */ | |
106 | //puts("no_timestamp!"); | |
107 | //goto end; | |
108 | } | |
109 | ||
110 | fputs(print_names ? "timestamp = " : "[", out); | |
111 | if (text->options.print_timestamp_cycles) { | |
112 | print_timestamp_cycles(text, clock, event); | |
113 | } else { | |
114 | print_timestamp_wall(text, clock, event); | |
115 | } | |
116 | ||
117 | fputs(print_names ? ", " : "] ", out); | |
118 | if (!text->options.print_delta_field) { | |
119 | goto end; | |
120 | } | |
121 | end: | |
122 | bt_put(stream); | |
123 | bt_put(clock); | |
124 | return ret; | |
125 | } | |
126 | ||
6a18b281 | 127 | static |
af9a82eb JG |
128 | enum bt_component_status print_event_header(struct text_component *text, |
129 | struct bt_ctf_event *event) | |
130 | { | |
6a18b281 MD |
131 | bool print_names = text->options.print_header_field_names; |
132 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
133 | struct bt_ctf_event_class *event_class = NULL; | |
af9a82eb | 134 | |
6a18b281 MD |
135 | event_class = bt_ctf_event_get_class(event); |
136 | if (!event_class) { | |
137 | ret = BT_COMPONENT_STATUS_ERROR; | |
138 | goto end; | |
139 | } | |
6e1bc0df MD |
140 | if (!text->start_line) { |
141 | fputs(", ", text->out); | |
142 | } | |
143 | text->start_line = false; | |
af9a82eb JG |
144 | ret = print_event_timestamp(text, event); |
145 | if (ret != BT_COMPONENT_STATUS_OK) { | |
146 | goto end; | |
147 | } | |
6a18b281 MD |
148 | if (print_names) { |
149 | fputs("name = ", text->out); | |
150 | } | |
af9a82eb | 151 | fputs(bt_ctf_event_class_get_name(event_class), text->out); |
f607e11e | 152 | bt_put(event_class); |
af9a82eb | 153 | end: |
6a18b281 MD |
154 | bt_put(event_class); |
155 | return ret; | |
156 | } | |
157 | ||
158 | static | |
159 | enum bt_component_status print_integer(struct text_component *text, | |
160 | struct bt_ctf_field *field) | |
161 | { | |
162 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
163 | struct bt_ctf_field_type *field_type = NULL; | |
164 | enum bt_ctf_integer_base base; | |
165 | enum bt_ctf_string_encoding encoding; | |
166 | int signedness; | |
167 | union { | |
168 | uint64_t u; | |
169 | int64_t s; | |
170 | } v; | |
171 | ||
172 | field_type = bt_ctf_field_get_type(field); | |
173 | if (!field_type) { | |
174 | ret = BT_COMPONENT_STATUS_ERROR; | |
175 | goto end; | |
176 | } | |
177 | signedness = bt_ctf_field_type_integer_get_signed(field_type); | |
178 | if (signedness < 0) { | |
179 | ret = BT_COMPONENT_STATUS_ERROR; | |
180 | goto end; | |
181 | } | |
182 | if (!signedness) { | |
183 | if (bt_ctf_field_unsigned_integer_get_value(field, &v.u) < 0) { | |
184 | ret = BT_COMPONENT_STATUS_ERROR; | |
185 | goto end; | |
186 | } | |
187 | } else { | |
188 | if (bt_ctf_field_signed_integer_get_value(field, &v.s) < 0) { | |
189 | ret = BT_COMPONENT_STATUS_ERROR; | |
190 | goto end; | |
191 | } | |
192 | } | |
193 | ||
194 | encoding = bt_ctf_field_type_integer_get_encoding(field_type); | |
195 | switch (encoding) { | |
196 | case BT_CTF_STRING_ENCODING_UTF8: | |
197 | case BT_CTF_STRING_ENCODING_ASCII: | |
198 | g_string_append_c(text->string, (int) v.u); | |
199 | goto end; | |
200 | case BT_CTF_STRING_ENCODING_NONE: | |
201 | case BT_CTF_STRING_ENCODING_UNKNOWN: | |
202 | break; | |
203 | default: | |
204 | ret = BT_COMPONENT_STATUS_ERROR; | |
205 | goto end; | |
206 | } | |
207 | ||
208 | base = bt_ctf_field_type_integer_get_base(field_type); | |
209 | switch (base) { | |
210 | case BT_CTF_INTEGER_BASE_BINARY: | |
211 | { | |
212 | int bitnr, len; | |
213 | ||
214 | len = bt_ctf_field_type_integer_get_size(field_type); | |
215 | if (len < 0) { | |
216 | ret = BT_COMPONENT_STATUS_ERROR; | |
217 | goto end; | |
218 | } | |
219 | fprintf(text->out, "0b"); | |
220 | v.u = _bt_piecewise_lshift(v.u, 64 - len); | |
221 | for (bitnr = 0; bitnr < len; bitnr++) { | |
222 | fprintf(text->out, "%u", (v.u & (1ULL << 63)) ? 1 : 0); | |
223 | v.u = _bt_piecewise_lshift(v.u, 1); | |
224 | } | |
225 | break; | |
226 | } | |
227 | case BT_CTF_INTEGER_BASE_OCTAL: | |
228 | { | |
229 | if (signedness) { | |
230 | int len; | |
231 | ||
232 | len = bt_ctf_field_type_integer_get_size(field_type); | |
233 | if (len < 0) { | |
234 | ret = BT_COMPONENT_STATUS_ERROR; | |
235 | goto end; | |
236 | } | |
237 | if (len < 64) { | |
238 | size_t rounded_len; | |
239 | ||
240 | assert(len != 0); | |
241 | /* Round length to the nearest 3-bit */ | |
242 | rounded_len = (((len - 1) / 3) + 1) * 3; | |
243 | v.u &= ((uint64_t) 1 << rounded_len) - 1; | |
244 | } | |
245 | } | |
246 | ||
247 | fprintf(text->out, "0%" PRIo64, v.u); | |
248 | break; | |
249 | } | |
250 | case BT_CTF_INTEGER_BASE_DECIMAL: | |
251 | if (!signedness) { | |
252 | fprintf(text->out, "%" PRIu64, v.u); | |
253 | } else { | |
254 | fprintf(text->out, "%" PRId64, v.s); | |
255 | } | |
256 | break; | |
257 | case BT_CTF_INTEGER_BASE_HEXADECIMAL: | |
258 | { | |
259 | int len; | |
260 | ||
261 | len = bt_ctf_field_type_integer_get_size(field_type); | |
262 | if (len < 0) { | |
263 | ret = BT_COMPONENT_STATUS_ERROR; | |
264 | goto end; | |
265 | } | |
266 | if (len < 64) { | |
267 | /* Round length to the nearest nibble */ | |
268 | uint8_t rounded_len = ((len + 3) & ~0x3); | |
269 | ||
270 | v.u &= ((uint64_t) 1 << rounded_len) - 1; | |
271 | } | |
272 | ||
273 | fprintf(text->out, "0x%" PRIX64, v.u); | |
274 | break; | |
275 | } | |
276 | default: | |
277 | ret = BT_COMPONENT_STATUS_ERROR; | |
278 | goto end; | |
279 | } | |
280 | end: | |
281 | bt_put(field_type); | |
282 | return ret; | |
283 | } | |
284 | ||
285 | static | |
286 | enum bt_component_status print_enum(struct text_component *text, | |
287 | struct bt_ctf_field *field) | |
288 | { | |
289 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
290 | struct bt_ctf_field *container_field = NULL; | |
291 | const char *mapping_name; | |
292 | ||
293 | container_field = bt_ctf_field_enumeration_get_container(field); | |
294 | if (!container_field) { | |
295 | ret = BT_COMPONENT_STATUS_ERROR; | |
296 | goto end; | |
297 | } | |
298 | mapping_name = bt_ctf_field_enumeration_get_mapping_name(field); | |
299 | if (mapping_name) { | |
300 | fprintf(text->out, "( \"%s\"", mapping_name); | |
301 | } else { | |
302 | fprintf(text->out, "( <unknown>"); | |
303 | } | |
304 | fprintf(text->out, " : container = "); | |
305 | ret = print_integer(text, container_field); | |
306 | if (ret != BT_COMPONENT_STATUS_OK) { | |
307 | goto end; | |
308 | } | |
309 | fprintf(text->out, " )"); | |
310 | end: | |
311 | bt_put(container_field); | |
312 | return ret; | |
313 | } | |
314 | ||
315 | static | |
316 | enum bt_component_status print_struct_field(struct text_component *text, | |
317 | struct bt_ctf_field *_struct, | |
318 | struct bt_ctf_field_type *struct_type, | |
319 | int i, bool print_names) | |
320 | { | |
321 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
322 | const char *field_name; | |
323 | struct bt_ctf_field *field = NULL; | |
324 | struct bt_ctf_field_type *field_type = NULL;; | |
325 | ||
326 | field = bt_ctf_field_structure_get_field_by_index(_struct, i); | |
327 | if (!field) { | |
328 | ret = BT_COMPONENT_STATUS_ERROR; | |
329 | goto end; | |
330 | } | |
331 | if (bt_ctf_field_type_structure_get_field(struct_type, | |
332 | &field_name, &field_type, i) < 0) { | |
333 | ret = BT_COMPONENT_STATUS_ERROR; | |
334 | goto end; | |
335 | } | |
336 | ||
337 | if (i != 0) { | |
338 | fprintf(text->out, ", "); | |
339 | } else { | |
340 | fprintf(text->out, " "); | |
341 | } | |
342 | if (print_names) { | |
343 | fprintf(text->out, "%s = ", rem_(field_name)); | |
344 | } | |
345 | ret = print_field(text, field, print_names); | |
346 | end: | |
347 | bt_put(field_type); | |
348 | bt_put(field); | |
349 | return ret; | |
350 | } | |
351 | ||
352 | static | |
353 | enum bt_component_status print_struct(struct text_component *text, | |
354 | struct bt_ctf_field *_struct, bool print_names) | |
355 | { | |
356 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
357 | struct bt_ctf_field_type *struct_type = NULL; | |
358 | int nr_fields, i; | |
359 | ||
360 | struct_type = bt_ctf_field_get_type(_struct); | |
361 | if (!struct_type) { | |
362 | ret = BT_COMPONENT_STATUS_ERROR; | |
363 | goto end; | |
364 | } | |
365 | nr_fields = bt_ctf_field_type_structure_get_field_count(struct_type); | |
366 | if (nr_fields < 0) { | |
367 | ret = BT_COMPONENT_STATUS_ERROR; | |
368 | goto end; | |
369 | } | |
370 | fprintf(text->out, "{"); | |
371 | text->depth++; | |
372 | for (i = 0; i < nr_fields; i++) { | |
373 | ret = print_struct_field(text, _struct, struct_type, i, | |
374 | print_names); | |
375 | if (ret != BT_COMPONENT_STATUS_OK) { | |
376 | goto end; | |
377 | } | |
378 | } | |
379 | text->depth--; | |
380 | fprintf(text->out, " }"); | |
381 | end: | |
382 | bt_put(struct_type); | |
383 | return ret; | |
384 | } | |
385 | ||
386 | static | |
387 | enum bt_component_status print_array_field(struct text_component *text, | |
388 | struct bt_ctf_field *array, uint64_t i, | |
389 | bool is_string, bool print_names) | |
390 | { | |
391 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
392 | struct bt_ctf_field *field = NULL; | |
393 | ||
394 | if (!is_string) { | |
395 | if (i != 0) { | |
396 | fprintf(text->out, ", "); | |
397 | } else { | |
398 | fprintf(text->out, " "); | |
399 | } | |
400 | } | |
401 | field = bt_ctf_field_array_get_field(array, i); | |
402 | if (!field) { | |
403 | ret = BT_COMPONENT_STATUS_ERROR; | |
404 | goto end; | |
405 | } | |
406 | ret = print_field(text, field, print_names); | |
407 | end: | |
408 | bt_put(field); | |
409 | return ret; | |
410 | } | |
411 | ||
412 | static | |
413 | enum bt_component_status print_array(struct text_component *text, | |
414 | struct bt_ctf_field *array, bool print_names) | |
415 | { | |
416 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
417 | struct bt_ctf_field_type *array_type = NULL, *field_type = NULL; | |
418 | enum bt_ctf_type_id type_id; | |
419 | int64_t len; | |
420 | uint64_t i; | |
421 | bool is_string = false; | |
422 | ||
423 | array_type = bt_ctf_field_get_type(array); | |
424 | if (!array_type) { | |
425 | ret = BT_COMPONENT_STATUS_ERROR; | |
426 | goto end; | |
427 | } | |
428 | field_type = bt_ctf_field_type_array_get_element_type(array_type); | |
429 | if (!field_type) { | |
430 | ret = BT_COMPONENT_STATUS_ERROR; | |
431 | goto end; | |
432 | } | |
433 | len = bt_ctf_field_type_array_get_length(array_type); | |
434 | if (len < 0) { | |
435 | ret = BT_COMPONENT_STATUS_ERROR; | |
436 | goto end; | |
437 | } | |
438 | type_id = bt_ctf_field_type_get_type_id(field_type); | |
439 | if (type_id == BT_CTF_TYPE_ID_INTEGER) { | |
440 | enum bt_ctf_string_encoding encoding; | |
441 | ||
442 | encoding = bt_ctf_field_type_integer_get_encoding(field_type); | |
443 | if (encoding == BT_CTF_STRING_ENCODING_UTF8 | |
444 | || encoding == BT_CTF_STRING_ENCODING_ASCII) { | |
445 | int integer_len, integer_alignment; | |
446 | ||
447 | integer_len = bt_ctf_field_type_integer_get_size(field_type); | |
448 | if (integer_len < 0) { | |
449 | return BT_COMPONENT_STATUS_ERROR; | |
450 | } | |
451 | integer_alignment = bt_ctf_field_type_get_alignment(field_type); | |
452 | if (integer_alignment < 0) { | |
453 | return BT_COMPONENT_STATUS_ERROR; | |
454 | } | |
455 | if (integer_len == CHAR_BIT | |
456 | && integer_alignment == CHAR_BIT) { | |
457 | is_string = true; | |
458 | } | |
459 | } | |
460 | } | |
461 | ||
462 | if (is_string) { | |
463 | g_string_assign(text->string, ""); | |
464 | } else { | |
465 | fprintf(text->out, "["); | |
466 | } | |
467 | ||
468 | text->depth++; | |
469 | for (i = 0; i < len; i++) { | |
470 | ret = print_array_field(text, array, i, is_string, print_names); | |
471 | if (ret != BT_COMPONENT_STATUS_OK) { | |
472 | goto end; | |
473 | } | |
474 | } | |
475 | text->depth--; | |
476 | ||
477 | if (is_string) { | |
478 | fprintf(text->out, "\"%s\"", text->string->str); | |
479 | } else { | |
480 | fprintf(text->out, " ]"); | |
481 | } | |
482 | end: | |
483 | bt_put(field_type); | |
484 | bt_put(array_type); | |
485 | return ret; | |
486 | } | |
487 | ||
488 | static | |
489 | enum bt_component_status print_sequence_field(struct text_component *text, | |
490 | struct bt_ctf_field *seq, uint64_t i, | |
491 | bool is_string, bool print_names) | |
492 | { | |
493 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
494 | struct bt_ctf_field *field = NULL; | |
495 | ||
496 | if (!is_string) { | |
497 | if (i != 0) { | |
498 | fprintf(text->out, ", "); | |
499 | } else { | |
500 | fprintf(text->out, " "); | |
501 | } | |
502 | } | |
503 | field = bt_ctf_field_sequence_get_field(seq, i); | |
504 | if (!field) { | |
505 | ret = BT_COMPONENT_STATUS_ERROR; | |
506 | goto end; | |
507 | } | |
508 | ret = print_field(text, field, print_names); | |
509 | end: | |
510 | bt_put(field); | |
511 | return ret; | |
512 | } | |
513 | ||
514 | static | |
515 | enum bt_component_status print_sequence(struct text_component *text, | |
516 | struct bt_ctf_field *seq, bool print_names) | |
517 | { | |
518 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
519 | struct bt_ctf_field_type *seq_type = NULL, *field_type = NULL; | |
520 | struct bt_ctf_field *length_field = NULL; | |
521 | enum bt_ctf_type_id type_id; | |
522 | uint64_t len; | |
523 | uint64_t i; | |
524 | bool is_string = false; | |
525 | ||
526 | seq_type = bt_ctf_field_get_type(seq); | |
527 | if (!seq_type) { | |
528 | ret = BT_COMPONENT_STATUS_ERROR; | |
529 | goto end; | |
530 | } | |
531 | length_field = bt_ctf_field_sequence_get_length(seq); | |
532 | if (!length_field) { | |
533 | ret = BT_COMPONENT_STATUS_ERROR; | |
534 | goto end; | |
535 | } | |
536 | if (bt_ctf_field_unsigned_integer_get_value(length_field, &len) < 0) { | |
537 | ret = BT_COMPONENT_STATUS_ERROR; | |
538 | goto end; | |
539 | } | |
540 | field_type = bt_ctf_field_type_sequence_get_element_type(seq_type); | |
541 | if (!field_type) { | |
542 | ret = BT_COMPONENT_STATUS_ERROR; | |
543 | goto end; | |
544 | } | |
545 | type_id = bt_ctf_field_type_get_type_id(field_type); | |
546 | if (type_id == BT_CTF_TYPE_ID_INTEGER) { | |
547 | enum bt_ctf_string_encoding encoding; | |
548 | ||
549 | encoding = bt_ctf_field_type_integer_get_encoding(field_type); | |
550 | if (encoding == BT_CTF_STRING_ENCODING_UTF8 | |
551 | || encoding == BT_CTF_STRING_ENCODING_ASCII) { | |
552 | int integer_len, integer_alignment; | |
553 | ||
554 | integer_len = bt_ctf_field_type_integer_get_size(field_type); | |
555 | if (integer_len < 0) { | |
556 | ret = BT_COMPONENT_STATUS_ERROR; | |
557 | goto end; | |
558 | } | |
559 | integer_alignment = bt_ctf_field_type_get_alignment(field_type); | |
560 | if (integer_alignment < 0) { | |
561 | ret = BT_COMPONENT_STATUS_ERROR; | |
562 | goto end; | |
563 | } | |
564 | if (integer_len == CHAR_BIT | |
565 | && integer_alignment == CHAR_BIT) { | |
566 | is_string = true; | |
567 | } | |
568 | } | |
569 | } | |
570 | ||
571 | if (is_string) { | |
572 | g_string_assign(text->string, ""); | |
573 | } else { | |
574 | fprintf(text->out, "["); | |
575 | } | |
576 | ||
577 | text->depth++; | |
578 | for (i = 0; i < len; i++) { | |
579 | ret = print_sequence_field(text, seq, i, | |
580 | is_string, print_names); | |
581 | if (ret != BT_COMPONENT_STATUS_OK) { | |
582 | goto end; | |
583 | } | |
584 | } | |
585 | text->depth--; | |
586 | ||
587 | if (is_string) { | |
588 | fprintf(text->out, "\"%s\"", text->string->str); | |
589 | } else { | |
590 | fprintf(text->out, " ]"); | |
591 | } | |
592 | end: | |
593 | bt_put(length_field); | |
594 | bt_put(field_type); | |
595 | bt_put(seq_type); | |
596 | return ret; | |
597 | } | |
598 | ||
599 | static | |
600 | enum bt_component_status print_variant(struct text_component *text, | |
601 | struct bt_ctf_field *variant, bool print_names) | |
602 | { | |
603 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
604 | struct bt_ctf_field *field = NULL; | |
605 | ||
606 | field = bt_ctf_field_variant_get_current_field(variant); | |
607 | if (!field) { | |
608 | ret = BT_COMPONENT_STATUS_ERROR; | |
609 | goto end; | |
610 | } | |
611 | fprintf(text->out, "{ "); | |
612 | text->depth++; | |
613 | if (print_names) { | |
614 | struct bt_ctf_field *tag_field = NULL; | |
615 | const char *tag_choice; | |
616 | ||
617 | tag_field = bt_ctf_field_variant_get_tag(variant); | |
618 | if (!tag_field) { | |
619 | ret = BT_COMPONENT_STATUS_ERROR; | |
620 | goto end; | |
621 | } | |
622 | tag_choice = bt_ctf_field_enumeration_get_mapping_name(tag_field); | |
623 | if (!tag_choice) { | |
624 | bt_put(tag_field); | |
625 | ret = BT_COMPONENT_STATUS_ERROR; | |
626 | goto end; | |
627 | } | |
628 | fprintf(text->out, "%s = ", rem_(tag_choice)); | |
629 | bt_put(tag_field); | |
630 | } | |
631 | ret = print_field(text, field, print_names); | |
632 | if (ret != BT_COMPONENT_STATUS_OK) { | |
633 | goto end; | |
634 | } | |
635 | text->depth--; | |
636 | fprintf(text->out, " }"); | |
637 | end: | |
638 | bt_put(field); | |
639 | return ret; | |
640 | } | |
641 | ||
642 | static | |
643 | enum bt_component_status print_field(struct text_component *text, | |
644 | struct bt_ctf_field *field, bool print_names) | |
645 | { | |
646 | enum bt_ctf_type_id type_id; | |
647 | ||
648 | type_id = bt_ctf_field_get_type_id(field); | |
649 | switch (type_id) { | |
650 | case CTF_TYPE_INTEGER: | |
651 | return print_integer(text, field); | |
652 | case CTF_TYPE_FLOAT: | |
653 | { | |
654 | double v; | |
655 | ||
656 | if (bt_ctf_field_floating_point_get_value(field, &v)) { | |
657 | return BT_COMPONENT_STATUS_ERROR; | |
658 | } | |
659 | fprintf(text->out, "%g", v); | |
660 | return BT_COMPONENT_STATUS_OK; | |
661 | } | |
662 | case CTF_TYPE_ENUM: | |
663 | return print_enum(text, field); | |
664 | case CTF_TYPE_STRING: | |
665 | fprintf(text->out, "\"%s\"", bt_ctf_field_string_get_value(field)); | |
666 | return BT_COMPONENT_STATUS_OK; | |
667 | case CTF_TYPE_STRUCT: | |
668 | return print_struct(text, field, print_names); | |
669 | case CTF_TYPE_UNTAGGED_VARIANT: | |
670 | case CTF_TYPE_VARIANT: | |
671 | return print_variant(text, field, print_names); | |
672 | case CTF_TYPE_ARRAY: | |
673 | return print_array(text, field, print_names); | |
674 | case CTF_TYPE_SEQUENCE: | |
675 | return print_sequence(text, field, print_names); | |
676 | default: | |
677 | fprintf(text->err, "[error] Unknown type id: %d\n", (int) type_id); | |
678 | return BT_COMPONENT_STATUS_ERROR; | |
679 | } | |
680 | } | |
681 | ||
682 | static | |
683 | enum bt_component_status print_stream_packet_context(struct text_component *text, | |
684 | struct bt_ctf_event *event) | |
685 | { | |
686 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
687 | struct bt_ctf_packet *packet = NULL; | |
688 | struct bt_ctf_field *main_field = NULL; | |
689 | ||
690 | packet = bt_ctf_event_get_packet(event); | |
691 | if (!packet) { | |
692 | ret = BT_COMPONENT_STATUS_ERROR; | |
693 | goto end; | |
694 | } | |
695 | main_field = bt_ctf_packet_get_context(packet); | |
696 | if (!main_field) { | |
697 | ret = BT_COMPONENT_STATUS_ERROR; | |
698 | goto end; | |
699 | } | |
6e1bc0df MD |
700 | if (!text->start_line) { |
701 | fputs(", ", text->out); | |
702 | } | |
703 | text->start_line = false; | |
6a18b281 | 704 | if (text->options.print_scope_field_names) { |
6e1bc0df | 705 | fputs("stream.packet.context = ", text->out); |
6a18b281 MD |
706 | } |
707 | ret = print_field(text, main_field, | |
708 | text->options.print_context_field_names); | |
709 | end: | |
710 | bt_put(main_field); | |
711 | bt_put(packet); | |
712 | return ret; | |
713 | } | |
714 | ||
715 | static | |
716 | enum bt_component_status print_event_header_raw(struct text_component *text, | |
717 | struct bt_ctf_event *event) | |
718 | { | |
719 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
720 | struct bt_ctf_field *main_field = NULL; | |
721 | ||
722 | main_field = bt_ctf_event_get_header(event); | |
723 | if (!main_field) { | |
724 | ret = BT_COMPONENT_STATUS_ERROR; | |
725 | goto end; | |
726 | } | |
6e1bc0df MD |
727 | if (!text->start_line) { |
728 | fputs(", ", text->out); | |
729 | } | |
730 | text->start_line = false; | |
6a18b281 | 731 | if (text->options.print_scope_field_names) { |
6e1bc0df | 732 | fputs("stream.event.header = ", text->out); |
6a18b281 MD |
733 | } |
734 | ret = print_field(text, main_field, | |
6e1bc0df | 735 | text->options.print_header_field_names); |
6a18b281 MD |
736 | end: |
737 | bt_put(main_field); | |
738 | return ret; | |
739 | } | |
740 | ||
741 | static | |
742 | enum bt_component_status print_stream_event_context(struct text_component *text, | |
743 | struct bt_ctf_event *event) | |
744 | { | |
745 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
746 | struct bt_ctf_field *main_field = NULL; | |
747 | ||
748 | main_field = bt_ctf_event_get_stream_event_context(event); | |
749 | if (!main_field) { | |
750 | ret = BT_COMPONENT_STATUS_ERROR; | |
751 | goto end; | |
752 | } | |
6e1bc0df MD |
753 | if (!text->start_line) { |
754 | fputs(", ", text->out); | |
755 | } | |
756 | text->start_line = false; | |
6a18b281 | 757 | if (text->options.print_scope_field_names) { |
6e1bc0df | 758 | fputs("stream.event.context = ", text->out); |
6a18b281 MD |
759 | } |
760 | ret = print_field(text, main_field, | |
761 | text->options.print_context_field_names); | |
762 | end: | |
763 | bt_put(main_field); | |
764 | return ret; | |
765 | } | |
766 | ||
767 | static | |
768 | enum bt_component_status print_event_context(struct text_component *text, | |
769 | struct bt_ctf_event *event) | |
770 | { | |
771 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
772 | struct bt_ctf_field *main_field = NULL; | |
773 | ||
774 | main_field = bt_ctf_event_get_event_context(event); | |
775 | if (!main_field) { | |
776 | ret = BT_COMPONENT_STATUS_ERROR; | |
777 | goto end; | |
778 | } | |
6e1bc0df MD |
779 | if (!text->start_line) { |
780 | fputs(", ", text->out); | |
781 | } | |
782 | text->start_line = false; | |
6a18b281 | 783 | if (text->options.print_scope_field_names) { |
6e1bc0df | 784 | fputs("event.context = ", text->out); |
6a18b281 MD |
785 | } |
786 | ret = print_field(text, main_field, | |
787 | text->options.print_context_field_names); | |
788 | end: | |
789 | bt_put(main_field); | |
790 | return ret; | |
791 | } | |
792 | ||
793 | static | |
794 | enum bt_component_status print_event_payload(struct text_component *text, | |
795 | struct bt_ctf_event *event) | |
796 | { | |
797 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
798 | struct bt_ctf_field *main_field = NULL; | |
799 | ||
800 | main_field = bt_ctf_event_get_payload_field(event); | |
801 | if (!main_field) { | |
802 | ret = BT_COMPONENT_STATUS_ERROR; | |
803 | goto end; | |
804 | } | |
6e1bc0df MD |
805 | if (!text->start_line) { |
806 | fputs(", ", text->out); | |
807 | } | |
808 | text->start_line = false; | |
6a18b281 | 809 | if (text->options.print_scope_field_names) { |
6e1bc0df | 810 | fputs("event.fields = ", text->out); |
6a18b281 MD |
811 | } |
812 | ret = print_field(text, main_field, | |
813 | text->options.print_payload_field_names); | |
814 | end: | |
815 | bt_put(main_field); | |
af9a82eb JG |
816 | return ret; |
817 | } | |
818 | ||
819 | BT_HIDDEN | |
820 | enum bt_component_status text_print_event(struct text_component *text, | |
821 | struct bt_ctf_event *event) | |
822 | { | |
823 | enum bt_component_status ret; | |
824 | ||
6e1bc0df | 825 | text->start_line = true; |
af9a82eb JG |
826 | ret = print_event_header(text, event); |
827 | if (ret != BT_COMPONENT_STATUS_OK) { | |
828 | goto end; | |
829 | } | |
6a18b281 MD |
830 | |
831 | ret = print_stream_packet_context(text, event); | |
832 | if (ret != BT_COMPONENT_STATUS_OK) { | |
833 | goto end; | |
834 | } | |
6a18b281 MD |
835 | |
836 | ret = print_event_header_raw(text, event); | |
837 | if (ret != BT_COMPONENT_STATUS_OK) { | |
838 | goto end; | |
839 | } | |
6a18b281 MD |
840 | |
841 | ret = print_stream_event_context(text, event); | |
842 | if (ret != BT_COMPONENT_STATUS_OK) { | |
843 | goto end; | |
844 | } | |
6a18b281 MD |
845 | |
846 | ret = print_event_context(text, event); | |
847 | if (ret != BT_COMPONENT_STATUS_OK) { | |
848 | goto end; | |
849 | } | |
6a18b281 MD |
850 | |
851 | ret = print_event_payload(text, event); | |
852 | if (ret != BT_COMPONENT_STATUS_OK) { | |
853 | goto end; | |
854 | } | |
af9a82eb JG |
855 | |
856 | fputc('\n', text->out); | |
857 | end: | |
858 | return ret; | |
859 | } |