7c8f37360702dda64c32168950112d7db0e47690
[libside.git] / src / tracer.c
1 // SPDX-License-Identifier: MIT
2 /*
3 * Copyright 2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
4 */
5
6 #include <stdint.h>
7 #include <inttypes.h>
8 #include <stdlib.h>
9 #include <stdio.h>
10
11 #include <side/trace.h>
12
13 static
14 void tracer_print_struct(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc);
15 static
16 void tracer_print_array(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc);
17 static
18 void tracer_print_vla(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc);
19 static
20 void tracer_print_vla_visitor(const struct side_type_description *type_desc, void *app_ctx);
21 static
22 void tracer_print_array_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item);
23 static
24 void tracer_print_vla_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item);
25 static
26 void tracer_print_dynamic(const struct side_arg_dynamic_vec *dynamic_item);
27
28 static
29 void tracer_print_attr_type(const struct side_attr *attr)
30 {
31 printf("{ key: \"%s\", value: ", attr->key);
32 switch (attr->value.type) {
33 case SIDE_ATTR_TYPE_BOOL:
34 printf("%s", attr->value.u.side_bool ? "true" : "false");
35 break;
36 case SIDE_ATTR_TYPE_U8:
37 printf("%" PRIu8, attr->value.u.side_u8);
38 break;
39 case SIDE_ATTR_TYPE_U16:
40 printf("%" PRIu16, attr->value.u.side_u16);
41 break;
42 case SIDE_ATTR_TYPE_U32:
43 printf("%" PRIu32, attr->value.u.side_u32);
44 break;
45 case SIDE_ATTR_TYPE_U64:
46 printf("%" PRIu64, attr->value.u.side_u64);
47 break;
48 case SIDE_ATTR_TYPE_S8:
49 printf("%" PRId8, attr->value.u.side_s8);
50 break;
51 case SIDE_ATTR_TYPE_S16:
52 printf("%" PRId16, attr->value.u.side_s16);
53 break;
54 case SIDE_ATTR_TYPE_S32:
55 printf("%" PRId32, attr->value.u.side_s32);
56 break;
57 case SIDE_ATTR_TYPE_S64:
58 printf("%" PRId64, attr->value.u.side_s64);
59 break;
60 case SIDE_ATTR_TYPE_FLOAT_BINARY16:
61 #if __HAVE_FLOAT16
62 printf("%g", (double) attr->value.u.side_float_binary16);
63 break;
64 #else
65 printf("ERROR: Unsupported binary16 float type\n");
66 abort();
67 #endif
68 case SIDE_ATTR_TYPE_FLOAT_BINARY32:
69 #if __HAVE_FLOAT32
70 printf("%g", (double) attr->value.u.side_float_binary32);
71 break;
72 #else
73 printf("ERROR: Unsupported binary32 float type\n");
74 abort();
75 #endif
76 case SIDE_ATTR_TYPE_FLOAT_BINARY64:
77 #if __HAVE_FLOAT64
78 printf("%g", (double) attr->value.u.side_float_binary64);
79 break;
80 #else
81 printf("ERROR: Unsupported binary64 float type\n");
82 abort();
83 #endif
84 case SIDE_ATTR_TYPE_FLOAT_BINARY128:
85 #if __HAVE_FLOAT128
86 printf("%Lg", (long double) attr->value.u.side_float_binary128);
87 break;
88 #else
89 printf("ERROR: Unsupported binary128 float type\n");
90 abort();
91 #endif
92 case SIDE_ATTR_TYPE_STRING:
93 printf("\"%s\"", attr->value.u.string);
94 break;
95 default:
96 printf("<UNKNOWN TYPE>");
97 abort();
98 }
99 printf(" }");
100 }
101
102 static
103 void print_attributes(const char *prefix_str, const struct side_attr *attr, uint32_t nr_attr)
104 {
105 int i;
106
107 if (!nr_attr)
108 return;
109 printf("%s[ ", prefix_str);
110 for (i = 0; i < nr_attr; i++) {
111 printf("%s", i ? ", " : "");
112 tracer_print_attr_type(&attr[i]);
113 }
114 printf(" ]");
115 }
116
117 static
118 void print_enum(const struct side_enum_mappings *side_enum_mappings, int64_t value)
119 {
120 int i, print_count = 0;
121
122 printf("%" PRId64 ", labels: [ ", value);
123 for (i = 0; i < side_enum_mappings->nr_mappings; i++) {
124 const struct side_enum_mapping *mapping = &side_enum_mappings->mappings[i];
125
126 if (value >= mapping->range_begin && value <= mapping->range_end) {
127 printf("%s", print_count++ ? ", " : "");
128 printf("\"%s\"", mapping->label);
129 }
130 }
131 if (!print_count)
132 printf("<NO LABEL>");
133 printf(" ]");
134 }
135
136 static
137 void tracer_print_type(const struct side_type_description *type_desc, const struct side_arg_vec *item)
138 {
139 switch (item->type) {
140 case SIDE_TYPE_ARRAY_U8:
141 case SIDE_TYPE_ARRAY_U16:
142 case SIDE_TYPE_ARRAY_U32:
143 case SIDE_TYPE_ARRAY_U64:
144 case SIDE_TYPE_ARRAY_S8:
145 case SIDE_TYPE_ARRAY_S16:
146 case SIDE_TYPE_ARRAY_S32:
147 case SIDE_TYPE_ARRAY_S64:
148 if (type_desc->type != SIDE_TYPE_ARRAY) {
149 printf("ERROR: type mismatch between description and arguments\n");
150 abort();
151 }
152 break;
153 case SIDE_TYPE_VLA_U8:
154 case SIDE_TYPE_VLA_U16:
155 case SIDE_TYPE_VLA_U32:
156 case SIDE_TYPE_VLA_U64:
157 case SIDE_TYPE_VLA_S8:
158 case SIDE_TYPE_VLA_S16:
159 case SIDE_TYPE_VLA_S32:
160 case SIDE_TYPE_VLA_S64:
161 if (type_desc->type != SIDE_TYPE_VLA) {
162 printf("ERROR: type mismatch between description and arguments\n");
163 abort();
164 }
165 break;
166
167 default:
168 if (type_desc->type != item->type) {
169 printf("ERROR: type mismatch between description and arguments\n");
170 abort();
171 }
172 break;
173 }
174 printf("{ ");
175 print_attributes("attr: ", type_desc->attr, type_desc->nr_attr);
176 printf("%s", type_desc->nr_attr ? ", " : "");
177 printf("value: ");
178 switch (item->type) {
179 case SIDE_TYPE_BOOL:
180 printf("%s", item->u.side_bool ? "true" : "false");
181 break;
182 case SIDE_TYPE_U8:
183 printf("%" PRIu8, item->u.side_u8);
184 break;
185 case SIDE_TYPE_U16:
186 printf("%" PRIu16, item->u.side_u16);
187 break;
188 case SIDE_TYPE_U32:
189 printf("%" PRIu32, item->u.side_u32);
190 break;
191 case SIDE_TYPE_U64:
192 printf("%" PRIu64, item->u.side_u64);
193 break;
194 case SIDE_TYPE_S8:
195 printf("%" PRId8, item->u.side_s8);
196 break;
197 case SIDE_TYPE_S16:
198 printf("%" PRId16, item->u.side_s16);
199 break;
200 case SIDE_TYPE_S32:
201 printf("%" PRId32, item->u.side_s32);
202 break;
203 case SIDE_TYPE_S64:
204 printf("%" PRId64, item->u.side_s64);
205 break;
206
207 case SIDE_TYPE_ENUM_U8:
208 print_enum(type_desc->u.side_enum_mappings,
209 (int64_t) item->u.side_u8);
210 break;
211 case SIDE_TYPE_ENUM_U16:
212 print_enum(type_desc->u.side_enum_mappings,
213 (int64_t) item->u.side_u16);
214 break;
215 case SIDE_TYPE_ENUM_U32:
216 print_enum(type_desc->u.side_enum_mappings,
217 (int64_t) item->u.side_u32);
218 break;
219 case SIDE_TYPE_ENUM_U64:
220 print_enum(type_desc->u.side_enum_mappings,
221 (int64_t) item->u.side_u64);
222 break;
223 case SIDE_TYPE_ENUM_S8:
224 print_enum(type_desc->u.side_enum_mappings,
225 (int64_t) item->u.side_s8);
226 break;
227 case SIDE_TYPE_ENUM_S16:
228 print_enum(type_desc->u.side_enum_mappings,
229 (int64_t) item->u.side_s16);
230 break;
231 case SIDE_TYPE_ENUM_S32:
232 print_enum(type_desc->u.side_enum_mappings,
233 (int64_t) item->u.side_s32);
234 break;
235 case SIDE_TYPE_ENUM_S64:
236 print_enum(type_desc->u.side_enum_mappings,
237 item->u.side_s64);
238 break;
239
240 case SIDE_TYPE_FLOAT_BINARY16:
241 #if __HAVE_FLOAT16
242 printf("%g", (double) item->u.side_float_binary16);
243 break;
244 #else
245 printf("ERROR: Unsupported binary16 float type\n");
246 abort();
247 #endif
248 case SIDE_TYPE_FLOAT_BINARY32:
249 #if __HAVE_FLOAT32
250 printf("%g", (double) item->u.side_float_binary32);
251 break;
252 #else
253 printf("ERROR: Unsupported binary32 float type\n");
254 abort();
255 #endif
256 case SIDE_TYPE_FLOAT_BINARY64:
257 #if __HAVE_FLOAT64
258 printf("%g", (double) item->u.side_float_binary64);
259 break;
260 #else
261 printf("ERROR: Unsupported binary64 float type\n");
262 abort();
263 #endif
264 case SIDE_TYPE_FLOAT_BINARY128:
265 #if __HAVE_FLOAT128
266 printf("%Lg", (long double) item->u.side_float_binary128);
267 break;
268 #else
269 printf("ERROR: Unsupported binary128 float type\n");
270 abort();
271 #endif
272 case SIDE_TYPE_STRING:
273 printf("\"%s\"", item->u.string);
274 break;
275 case SIDE_TYPE_STRUCT:
276 tracer_print_struct(type_desc, item->u.side_struct);
277 break;
278 case SIDE_TYPE_ARRAY:
279 tracer_print_array(type_desc, item->u.side_array);
280 break;
281 case SIDE_TYPE_VLA:
282 tracer_print_vla(type_desc, item->u.side_vla);
283 break;
284 case SIDE_TYPE_VLA_VISITOR:
285 tracer_print_vla_visitor(type_desc, item->u.side_vla_app_visitor_ctx);
286 break;
287 case SIDE_TYPE_ARRAY_U8:
288 case SIDE_TYPE_ARRAY_U16:
289 case SIDE_TYPE_ARRAY_U32:
290 case SIDE_TYPE_ARRAY_U64:
291 case SIDE_TYPE_ARRAY_S8:
292 case SIDE_TYPE_ARRAY_S16:
293 case SIDE_TYPE_ARRAY_S32:
294 case SIDE_TYPE_ARRAY_S64:
295 tracer_print_array_fixint(type_desc, item);
296 break;
297 case SIDE_TYPE_VLA_U8:
298 case SIDE_TYPE_VLA_U16:
299 case SIDE_TYPE_VLA_U32:
300 case SIDE_TYPE_VLA_U64:
301 case SIDE_TYPE_VLA_S8:
302 case SIDE_TYPE_VLA_S16:
303 case SIDE_TYPE_VLA_S32:
304 case SIDE_TYPE_VLA_S64:
305 tracer_print_vla_fixint(type_desc, item);
306 break;
307 case SIDE_TYPE_DYNAMIC:
308 tracer_print_dynamic(&item->u.dynamic);
309 break;
310 default:
311 printf("<UNKNOWN TYPE>");
312 abort();
313 }
314 printf(" }");
315 }
316
317 static
318 void tracer_print_field(const struct side_event_field *item_desc, const struct side_arg_vec *item)
319 {
320 printf("%s: ", item_desc->field_name);
321 tracer_print_type(&item_desc->side_type, item);
322 }
323
324 static
325 void tracer_print_struct(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc)
326 {
327 const struct side_arg_vec *sav = sav_desc->sav;
328 uint32_t side_sav_len = sav_desc->len;
329 int i;
330
331 if (type_desc->u.side_struct.nr_fields != side_sav_len) {
332 printf("ERROR: number of fields mismatch between description and arguments of structure\n");
333 abort();
334 }
335 printf("{ ");
336 for (i = 0; i < side_sav_len; i++) {
337 printf("%s", i ? ", " : "");
338 tracer_print_field(&type_desc->u.side_struct.fields[i], &sav[i]);
339 }
340 printf(" }");
341 }
342
343 static
344 void tracer_print_array(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc)
345 {
346 const struct side_arg_vec *sav = sav_desc->sav;
347 uint32_t side_sav_len = sav_desc->len;
348 int i;
349
350 if (type_desc->u.side_array.length != side_sav_len) {
351 printf("ERROR: length mismatch between description and arguments of array\n");
352 abort();
353 }
354 printf("[ ");
355 for (i = 0; i < side_sav_len; i++) {
356 printf("%s", i ? ", " : "");
357 tracer_print_type(type_desc->u.side_array.elem_type, &sav[i]);
358 }
359 printf(" ]");
360 }
361
362 static
363 void tracer_print_vla(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc)
364 {
365 const struct side_arg_vec *sav = sav_desc->sav;
366 uint32_t side_sav_len = sav_desc->len;
367 int i;
368
369 printf("[ ");
370 for (i = 0; i < side_sav_len; i++) {
371 printf("%s", i ? ", " : "");
372 tracer_print_type(type_desc->u.side_vla.elem_type, &sav[i]);
373 }
374 printf(" ]");
375 }
376
377 struct tracer_visitor_priv {
378 const struct side_type_description *elem_type;
379 int i;
380 };
381
382 static
383 enum side_visitor_status tracer_write_elem_cb(const struct side_tracer_visitor_ctx *tracer_ctx,
384 const struct side_arg_vec *elem)
385 {
386 struct tracer_visitor_priv *tracer_priv = tracer_ctx->priv;
387
388 printf("%s", tracer_priv->i++ ? ", " : "");
389 tracer_print_type(tracer_priv->elem_type, elem);
390 return SIDE_VISITOR_STATUS_OK;
391 }
392
393 static
394 void tracer_print_vla_visitor(const struct side_type_description *type_desc, void *app_ctx)
395 {
396 enum side_visitor_status status;
397 struct tracer_visitor_priv tracer_priv = {
398 .elem_type = type_desc->u.side_vla_visitor.elem_type,
399 .i = 0,
400 };
401 const struct side_tracer_visitor_ctx tracer_ctx = {
402 .write_elem = tracer_write_elem_cb,
403 .priv = &tracer_priv,
404 };
405
406 printf("[ ");
407 status = type_desc->u.side_vla_visitor.visitor(&tracer_ctx, app_ctx);
408 switch (status) {
409 case SIDE_VISITOR_STATUS_OK:
410 break;
411 case SIDE_VISITOR_STATUS_ERROR:
412 printf("ERROR: Visitor error\n");
413 abort();
414 }
415 printf(" ]");
416 }
417
418 void tracer_print_array_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item)
419 {
420 const struct side_type_description *elem_type = type_desc->u.side_array.elem_type;
421 uint32_t side_sav_len = type_desc->u.side_array.length;
422 void *p = item->u.side_array_fixint;
423 enum side_type side_type;
424 int i;
425
426 switch (item->type) {
427 case SIDE_TYPE_ARRAY_U8:
428 if (elem_type->type != SIDE_TYPE_U8)
429 goto type_error;
430 break;
431 case SIDE_TYPE_ARRAY_U16:
432 if (elem_type->type != SIDE_TYPE_U16)
433 goto type_error;
434 break;
435 case SIDE_TYPE_ARRAY_U32:
436 if (elem_type->type != SIDE_TYPE_U32)
437 goto type_error;
438 break;
439 case SIDE_TYPE_ARRAY_U64:
440 if (elem_type->type != SIDE_TYPE_U64)
441 goto type_error;
442 break;
443 case SIDE_TYPE_ARRAY_S8:
444 if (elem_type->type != SIDE_TYPE_S8)
445 goto type_error;
446 break;
447 case SIDE_TYPE_ARRAY_S16:
448 if (elem_type->type != SIDE_TYPE_S16)
449 goto type_error;
450 break;
451 case SIDE_TYPE_ARRAY_S32:
452 if (elem_type->type != SIDE_TYPE_S32)
453 goto type_error;
454 break;
455 case SIDE_TYPE_ARRAY_S64:
456 if (elem_type->type != SIDE_TYPE_S64)
457 goto type_error;
458 break;
459 default:
460 goto type_error;
461 }
462 side_type = elem_type->type;
463
464 printf("[ ");
465 for (i = 0; i < side_sav_len; i++) {
466 struct side_arg_vec sav_elem = {
467 .type = side_type,
468 };
469
470 switch (side_type) {
471 case SIDE_TYPE_U8:
472 sav_elem.u.side_u8 = ((const uint8_t *) p)[i];
473 break;
474 case SIDE_TYPE_S8:
475 sav_elem.u.side_s8 = ((const int8_t *) p)[i];
476 break;
477 case SIDE_TYPE_U16:
478 sav_elem.u.side_u16 = ((const uint16_t *) p)[i];
479 break;
480 case SIDE_TYPE_S16:
481 sav_elem.u.side_s16 = ((const int16_t *) p)[i];
482 break;
483 case SIDE_TYPE_U32:
484 sav_elem.u.side_u32 = ((const uint32_t *) p)[i];
485 break;
486 case SIDE_TYPE_S32:
487 sav_elem.u.side_s32 = ((const int32_t *) p)[i];
488 break;
489 case SIDE_TYPE_U64:
490 sav_elem.u.side_u64 = ((const uint64_t *) p)[i];
491 break;
492 case SIDE_TYPE_S64:
493 sav_elem.u.side_s64 = ((const int64_t *) p)[i];
494 break;
495
496 default:
497 printf("ERROR: Unexpected type\n");
498 abort();
499 }
500
501 printf("%s", i ? ", " : "");
502 tracer_print_type(elem_type, &sav_elem);
503 }
504 printf(" ]");
505 return;
506
507 type_error:
508 printf("ERROR: type mismatch\n");
509 abort();
510 }
511
512 void tracer_print_vla_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item)
513 {
514 const struct side_type_description *elem_type = type_desc->u.side_vla.elem_type;
515 uint32_t side_sav_len = item->u.side_vla_fixint.length;
516 void *p = item->u.side_vla_fixint.p;
517 enum side_type side_type;
518 int i;
519
520 switch (item->type) {
521 case SIDE_TYPE_VLA_U8:
522 if (elem_type->type != SIDE_TYPE_U8)
523 goto type_error;
524 break;
525 case SIDE_TYPE_VLA_U16:
526 if (elem_type->type != SIDE_TYPE_U16)
527 goto type_error;
528 break;
529 case SIDE_TYPE_VLA_U32:
530 if (elem_type->type != SIDE_TYPE_U32)
531 goto type_error;
532 break;
533 case SIDE_TYPE_VLA_U64:
534 if (elem_type->type != SIDE_TYPE_U64)
535 goto type_error;
536 break;
537 case SIDE_TYPE_VLA_S8:
538 if (elem_type->type != SIDE_TYPE_S8)
539 goto type_error;
540 break;
541 case SIDE_TYPE_VLA_S16:
542 if (elem_type->type != SIDE_TYPE_S16)
543 goto type_error;
544 break;
545 case SIDE_TYPE_VLA_S32:
546 if (elem_type->type != SIDE_TYPE_S32)
547 goto type_error;
548 break;
549 case SIDE_TYPE_VLA_S64:
550 if (elem_type->type != SIDE_TYPE_S64)
551 goto type_error;
552 break;
553 default:
554 goto type_error;
555 }
556 side_type = elem_type->type;
557
558 printf("[ ");
559 for (i = 0; i < side_sav_len; i++) {
560 struct side_arg_vec sav_elem = {
561 .type = side_type,
562 };
563
564 switch (side_type) {
565 case SIDE_TYPE_U8:
566 sav_elem.u.side_u8 = ((const uint8_t *) p)[i];
567 break;
568 case SIDE_TYPE_S8:
569 sav_elem.u.side_s8 = ((const int8_t *) p)[i];
570 break;
571 case SIDE_TYPE_U16:
572 sav_elem.u.side_u16 = ((const uint16_t *) p)[i];
573 break;
574 case SIDE_TYPE_S16:
575 sav_elem.u.side_s16 = ((const int16_t *) p)[i];
576 break;
577 case SIDE_TYPE_U32:
578 sav_elem.u.side_u32 = ((const uint32_t *) p)[i];
579 break;
580 case SIDE_TYPE_S32:
581 sav_elem.u.side_s32 = ((const int32_t *) p)[i];
582 break;
583 case SIDE_TYPE_U64:
584 sav_elem.u.side_u64 = ((const uint64_t *) p)[i];
585 break;
586 case SIDE_TYPE_S64:
587 sav_elem.u.side_s64 = ((const int64_t *) p)[i];
588 break;
589
590 default:
591 printf("ERROR: Unexpected type\n");
592 abort();
593 }
594
595 printf("%s", i ? ", " : "");
596 tracer_print_type(elem_type, &sav_elem);
597 }
598 printf(" ]");
599 return;
600
601 type_error:
602 printf("ERROR: type mismatch\n");
603 abort();
604 }
605
606 static
607 void tracer_print_dynamic_struct(const struct side_arg_dynamic_event_struct *dynamic_struct)
608 {
609 const struct side_arg_dynamic_event_field *fields = dynamic_struct->fields;
610 uint32_t len = dynamic_struct->len;
611 int i;
612
613 printf("[ ");
614 for (i = 0; i < len; i++) {
615 printf("%s", i ? ", " : "");
616 printf("%s:: ", fields[i].field_name);
617 tracer_print_dynamic(&fields[i].elem);
618 }
619 printf(" ]");
620 }
621
622 struct tracer_dynamic_struct_visitor_priv {
623 int i;
624 };
625
626 static
627 enum side_visitor_status tracer_dynamic_struct_write_elem_cb(
628 const struct side_tracer_dynamic_struct_visitor_ctx *tracer_ctx,
629 const struct side_arg_dynamic_event_field *dynamic_field)
630 {
631 struct tracer_dynamic_struct_visitor_priv *tracer_priv = tracer_ctx->priv;
632
633 printf("%s", tracer_priv->i++ ? ", " : "");
634 printf("%s:: ", dynamic_field->field_name);
635 tracer_print_dynamic(&dynamic_field->elem);
636 return SIDE_VISITOR_STATUS_OK;
637 }
638
639 static
640 void tracer_print_dynamic_struct_visitor(const struct side_arg_dynamic_vec *item)
641 {
642 enum side_visitor_status status;
643 struct tracer_dynamic_struct_visitor_priv tracer_priv = {
644 .i = 0,
645 };
646 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx = {
647 .write_field = tracer_dynamic_struct_write_elem_cb,
648 .priv = &tracer_priv,
649 };
650 void *app_ctx = item->u.side_dynamic_struct_visitor.app_ctx;
651
652 printf("[ ");
653 status = item->u.side_dynamic_struct_visitor.visitor(&tracer_ctx, app_ctx);
654 switch (status) {
655 case SIDE_VISITOR_STATUS_OK:
656 break;
657 case SIDE_VISITOR_STATUS_ERROR:
658 printf("ERROR: Visitor error\n");
659 abort();
660 }
661 printf(" ]");
662 }
663
664 static
665 void tracer_print_dynamic_vla(const struct side_arg_dynamic_vec_vla *vla)
666 {
667 const struct side_arg_dynamic_vec *sav = vla->sav;
668 uint32_t side_sav_len = vla->len;
669 int i;
670
671 printf("[ ");
672 for (i = 0; i < side_sav_len; i++) {
673 printf("%s", i ? ", " : "");
674 tracer_print_dynamic(&sav[i]);
675 }
676 printf(" ]");
677 }
678
679 struct tracer_dynamic_vla_visitor_priv {
680 int i;
681 };
682
683 static
684 enum side_visitor_status tracer_dynamic_vla_write_elem_cb(
685 const struct side_tracer_dynamic_vla_visitor_ctx *tracer_ctx,
686 const struct side_arg_dynamic_vec *elem)
687 {
688 struct tracer_dynamic_vla_visitor_priv *tracer_priv = tracer_ctx->priv;
689
690 printf("%s", tracer_priv->i++ ? ", " : "");
691 tracer_print_dynamic(elem);
692 return SIDE_VISITOR_STATUS_OK;
693 }
694
695 static
696 void tracer_print_dynamic_vla_visitor(const struct side_arg_dynamic_vec *item)
697 {
698 enum side_visitor_status status;
699 struct tracer_dynamic_vla_visitor_priv tracer_priv = {
700 .i = 0,
701 };
702 const struct side_tracer_dynamic_vla_visitor_ctx tracer_ctx = {
703 .write_elem = tracer_dynamic_vla_write_elem_cb,
704 .priv = &tracer_priv,
705 };
706 void *app_ctx = item->u.side_dynamic_vla_visitor.app_ctx;
707
708 printf("[ ");
709 status = item->u.side_dynamic_vla_visitor.visitor(&tracer_ctx, app_ctx);
710 switch (status) {
711 case SIDE_VISITOR_STATUS_OK:
712 break;
713 case SIDE_VISITOR_STATUS_ERROR:
714 printf("ERROR: Visitor error\n");
715 abort();
716 }
717 printf(" ]");
718 }
719
720 static
721 void tracer_print_dynamic(const struct side_arg_dynamic_vec *item)
722 {
723 printf("{ ");
724 print_attributes("attr:: ", item->attr, item->nr_attr);
725 printf("%s", item->nr_attr ? ", " : "");
726 printf("value: ");
727 switch (item->dynamic_type) {
728 case SIDE_DYNAMIC_TYPE_NULL:
729 printf("<NULL TYPE>");
730 break;
731 case SIDE_DYNAMIC_TYPE_BOOL:
732 printf("%s", item->u.side_bool ? "true" : "false");
733 break;
734 case SIDE_DYNAMIC_TYPE_U8:
735 printf("%" PRIu8, item->u.side_u8);
736 break;
737 case SIDE_DYNAMIC_TYPE_U16:
738 printf("%" PRIu16, item->u.side_u16);
739 break;
740 case SIDE_DYNAMIC_TYPE_U32:
741 printf("%" PRIu32, item->u.side_u32);
742 break;
743 case SIDE_DYNAMIC_TYPE_U64:
744 printf("%" PRIu64, item->u.side_u64);
745 break;
746 case SIDE_DYNAMIC_TYPE_S8:
747 printf("%" PRId8, item->u.side_s8);
748 break;
749 case SIDE_DYNAMIC_TYPE_S16:
750 printf("%" PRId16, item->u.side_s16);
751 break;
752 case SIDE_DYNAMIC_TYPE_S32:
753 printf("%" PRId32, item->u.side_s32);
754 break;
755 case SIDE_DYNAMIC_TYPE_S64:
756 printf("%" PRId64, item->u.side_s64);
757 break;
758 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY16:
759 #if __HAVE_FLOAT16
760 printf("%g", (double) item->u.side_float_binary16);
761 break;
762 #else
763 printf("ERROR: Unsupported binary16 float type\n");
764 abort();
765 #endif
766 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY32:
767 #if __HAVE_FLOAT32
768 printf("%g", (double) item->u.side_float_binary32);
769 break;
770 #else
771 printf("ERROR: Unsupported binary32 float type\n");
772 abort();
773 #endif
774 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY64:
775 #if __HAVE_FLOAT64
776 printf("%g", (double) item->u.side_float_binary64);
777 break;
778 #else
779 printf("ERROR: Unsupported binary64 float type\n");
780 abort();
781 #endif
782 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY128:
783 #if __HAVE_FLOAT128
784 printf("%Lg", (long double) item->u.side_float_binary128);
785 break;
786 #else
787 printf("ERROR: Unsupported binary128 float type\n");
788 abort();
789 #endif
790 case SIDE_DYNAMIC_TYPE_STRING:
791 printf("\"%s\"", item->u.string);
792 break;
793 case SIDE_DYNAMIC_TYPE_STRUCT:
794 tracer_print_dynamic_struct(item->u.side_dynamic_struct);
795 break;
796 case SIDE_DYNAMIC_TYPE_STRUCT_VISITOR:
797 tracer_print_dynamic_struct_visitor(item);
798 break;
799 case SIDE_DYNAMIC_TYPE_VLA:
800 tracer_print_dynamic_vla(item->u.side_dynamic_vla);
801 break;
802 case SIDE_DYNAMIC_TYPE_VLA_VISITOR:
803 tracer_print_dynamic_vla_visitor(item);
804 break;
805 default:
806 printf("<UNKNOWN TYPE>");
807 abort();
808 }
809 printf(" }");
810 }
811
812 static
813 void tracer_print_static_fields(const struct side_event_description *desc,
814 const struct side_arg_vec_description *sav_desc,
815 int *nr_items)
816 {
817 const struct side_arg_vec *sav = sav_desc->sav;
818 uint32_t side_sav_len = sav_desc->len;
819 int i;
820
821 printf("provider: %s, event: %s", desc->provider_name, desc->event_name);
822 if (desc->nr_fields != side_sav_len) {
823 printf("ERROR: number of fields mismatch between description and arguments\n");
824 abort();
825 }
826 print_attributes(", attributes: ", desc->attr, desc->nr_attr);
827 printf("%s", side_sav_len ? ", fields: [ " : "");
828 for (i = 0; i < side_sav_len; i++) {
829 printf("%s", i ? ", " : "");
830 tracer_print_field(&desc->fields[i], &sav[i]);
831 }
832 if (nr_items)
833 *nr_items = i;
834 }
835
836 void tracer_call(const struct side_event_description *desc, const struct side_arg_vec_description *sav_desc)
837 {
838 int nr_fields = 0;
839
840 if (side_unlikely(desc->flags & SIDE_EVENT_FLAG_VARIADIC)) {
841 printf("ERROR: unexpected variadic event description\n");
842 abort();
843 }
844 tracer_print_static_fields(desc, sav_desc, &nr_fields);
845 if (nr_fields)
846 printf(" ]");
847 printf("\n");
848 }
849
850 void tracer_call_variadic(const struct side_event_description *desc,
851 const struct side_arg_vec_description *sav_desc,
852 const struct side_arg_dynamic_event_struct *var_struct)
853 {
854 uint32_t var_struct_len = var_struct->len;
855 int nr_fields = 0, i;
856
857 tracer_print_static_fields(desc, sav_desc, &nr_fields);
858
859 if (side_unlikely(!(desc->flags & SIDE_EVENT_FLAG_VARIADIC))) {
860 printf("ERROR: unexpected non-variadic event description\n");
861 abort();
862 }
863 printf("%s", var_struct_len && !nr_fields ? ", fields: [ " : "");
864 for (i = 0; i < var_struct_len; i++, nr_fields++) {
865 printf("%s", nr_fields ? ", " : "");
866 printf("%s:: ", var_struct->fields[i].field_name);
867 tracer_print_dynamic(&var_struct->fields[i].elem);
868 }
869 if (i)
870 printf(" ]");
871 printf("\n");
872 }
This page took 0.045684 seconds and 4 git commands to generate.