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