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