Refactor common code
[libside.git] / src / tracer.c
CommitLineData
f611d0c3
MD
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
13static
14void tracer_print_struct(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc);
15static
16void tracer_print_array(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc);
17static
18void tracer_print_vla(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc);
19static
352a4b77 20void tracer_print_vla_visitor(const struct side_type_description *type_desc, void *app_ctx);
ba845af5
MD
21static
22void tracer_print_array_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item);
1533629f
MD
23static
24void tracer_print_vla_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item);
a2e2357e
MD
25static
26void tracer_print_dynamic(const struct side_arg_dynamic_vec *dynamic_item);
f611d0c3
MD
27
28static
29void tracer_print_type(const struct side_type_description *type_desc, const struct side_arg_vec *item)
30{
ba845af5
MD
31 switch (item->type) {
32 case SIDE_TYPE_ARRAY_U8:
33 case SIDE_TYPE_ARRAY_U16:
34 case SIDE_TYPE_ARRAY_U32:
35 case SIDE_TYPE_ARRAY_U64:
36 case SIDE_TYPE_ARRAY_S8:
37 case SIDE_TYPE_ARRAY_S16:
38 case SIDE_TYPE_ARRAY_S32:
39 case SIDE_TYPE_ARRAY_S64:
40 if (type_desc->type != SIDE_TYPE_ARRAY) {
41 printf("ERROR: type mismatch between description and arguments\n");
42 abort();
43 }
44 break;
1533629f
MD
45 case SIDE_TYPE_VLA_U8:
46 case SIDE_TYPE_VLA_U16:
47 case SIDE_TYPE_VLA_U32:
48 case SIDE_TYPE_VLA_U64:
49 case SIDE_TYPE_VLA_S8:
50 case SIDE_TYPE_VLA_S16:
51 case SIDE_TYPE_VLA_S32:
52 case SIDE_TYPE_VLA_S64:
53 if (type_desc->type != SIDE_TYPE_VLA) {
54 printf("ERROR: type mismatch between description and arguments\n");
55 abort();
56 }
57 break;
58
ba845af5 59 default:
a2e2357e 60 if (type_desc->type != item->type) {
ba845af5
MD
61 printf("ERROR: type mismatch between description and arguments\n");
62 abort();
63 }
64 break;
f611d0c3 65 }
f611d0c3
MD
66 switch (item->type) {
67 case SIDE_TYPE_U8:
68 printf("%" PRIu8, item->u.side_u8);
69 break;
70 case SIDE_TYPE_U16:
71 printf("%" PRIu16, item->u.side_u16);
72 break;
73 case SIDE_TYPE_U32:
74 printf("%" PRIu32, item->u.side_u32);
75 break;
76 case SIDE_TYPE_U64:
77 printf("%" PRIu64, item->u.side_u64);
78 break;
79 case SIDE_TYPE_S8:
80 printf("%" PRId8, item->u.side_s8);
81 break;
82 case SIDE_TYPE_S16:
83 printf("%" PRId16, item->u.side_s16);
84 break;
85 case SIDE_TYPE_S32:
86 printf("%" PRId32, item->u.side_s32);
87 break;
88 case SIDE_TYPE_S64:
89 printf("%" PRId64, item->u.side_s64);
90 break;
91 case SIDE_TYPE_STRING:
a2e2357e 92 printf("\"%s\"", item->u.string);
f611d0c3
MD
93 break;
94 case SIDE_TYPE_STRUCT:
95 tracer_print_struct(type_desc, item->u.side_struct);
96 break;
97 case SIDE_TYPE_ARRAY:
98 tracer_print_array(type_desc, item->u.side_array);
99 break;
100 case SIDE_TYPE_VLA:
101 tracer_print_vla(type_desc, item->u.side_vla);
102 break;
103 case SIDE_TYPE_VLA_VISITOR:
352a4b77 104 tracer_print_vla_visitor(type_desc, item->u.side_vla_app_visitor_ctx);
f611d0c3 105 break;
ba845af5
MD
106 case SIDE_TYPE_ARRAY_U8:
107 case SIDE_TYPE_ARRAY_U16:
108 case SIDE_TYPE_ARRAY_U32:
109 case SIDE_TYPE_ARRAY_U64:
110 case SIDE_TYPE_ARRAY_S8:
111 case SIDE_TYPE_ARRAY_S16:
112 case SIDE_TYPE_ARRAY_S32:
113 case SIDE_TYPE_ARRAY_S64:
114 tracer_print_array_fixint(type_desc, item);
115 break;
1533629f
MD
116 case SIDE_TYPE_VLA_U8:
117 case SIDE_TYPE_VLA_U16:
118 case SIDE_TYPE_VLA_U32:
119 case SIDE_TYPE_VLA_U64:
120 case SIDE_TYPE_VLA_S8:
121 case SIDE_TYPE_VLA_S16:
122 case SIDE_TYPE_VLA_S32:
123 case SIDE_TYPE_VLA_S64:
124 tracer_print_vla_fixint(type_desc, item);
125 break;
a2e2357e
MD
126 case SIDE_TYPE_DYNAMIC:
127 tracer_print_dynamic(&item->u.dynamic);
128 break;
f611d0c3
MD
129 default:
130 printf("<UNKNOWN TYPE>");
131 abort();
132 }
133}
134
135static
136void tracer_print_field(const struct side_event_field *item_desc, const struct side_arg_vec *item)
137{
19fa6aa2 138 printf("%s: ", item_desc->field_name);
f611d0c3 139 tracer_print_type(&item_desc->side_type, item);
f611d0c3
MD
140}
141
142static
143void tracer_print_struct(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc)
144{
145 const struct side_arg_vec *sav = sav_desc->sav;
146 uint32_t side_sav_len = sav_desc->len;
147 int i;
148
149 if (type_desc->u.side_struct.nr_fields != side_sav_len) {
150 printf("ERROR: number of fields mismatch between description and arguments of structure\n");
151 abort();
152 }
153 printf("{ ");
154 for (i = 0; i < side_sav_len; i++) {
155 printf("%s", i ? ", " : "");
156 tracer_print_field(&type_desc->u.side_struct.fields[i], &sav[i]);
157 }
158 printf(" }");
159}
160
161static
162void tracer_print_array(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc)
163{
164 const struct side_arg_vec *sav = sav_desc->sav;
165 uint32_t side_sav_len = sav_desc->len;
166 int i;
167
168 if (type_desc->u.side_array.length != side_sav_len) {
169 printf("ERROR: length mismatch between description and arguments of array\n");
170 abort();
171 }
172 printf("[ ");
173 for (i = 0; i < side_sav_len; i++) {
174 printf("%s", i ? ", " : "");
175 tracer_print_type(type_desc->u.side_array.elem_type, &sav[i]);
176 }
177 printf(" ]");
178}
179
180static
181void tracer_print_vla(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc)
182{
183 const struct side_arg_vec *sav = sav_desc->sav;
184 uint32_t side_sav_len = sav_desc->len;
185 int i;
186
187 printf("[ ");
188 for (i = 0; i < side_sav_len; i++) {
189 printf("%s", i ? ", " : "");
190 tracer_print_type(type_desc->u.side_vla.elem_type, &sav[i]);
191 }
192 printf(" ]");
193}
194
352a4b77
MD
195struct tracer_visitor_priv {
196 const struct side_type_description *elem_type;
197 int i;
198};
199
200static
201enum side_visitor_status tracer_write_elem_cb(const struct side_tracer_visitor_ctx *tracer_ctx,
202 const struct side_arg_vec *elem)
203{
204 struct tracer_visitor_priv *tracer_priv = tracer_ctx->priv;
205
206 printf("%s", tracer_priv->i++ ? ", " : "");
207 tracer_print_type(tracer_priv->elem_type, elem);
208 return SIDE_VISITOR_STATUS_OK;
209}
210
f611d0c3 211static
352a4b77 212void tracer_print_vla_visitor(const struct side_type_description *type_desc, void *app_ctx)
f611d0c3
MD
213{
214 enum side_visitor_status status;
352a4b77
MD
215 struct tracer_visitor_priv tracer_priv = {
216 .elem_type = type_desc->u.side_vla_visitor.elem_type,
217 .i = 0,
218 };
219 const struct side_tracer_visitor_ctx tracer_ctx = {
220 .write_elem = tracer_write_elem_cb,
221 .priv = &tracer_priv,
222 };
f611d0c3 223
352a4b77
MD
224 printf("[ ");
225 status = type_desc->u.side_vla_visitor.visitor(&tracer_ctx, app_ctx);
226 switch (status) {
227 case SIDE_VISITOR_STATUS_OK:
228 break;
229 case SIDE_VISITOR_STATUS_ERROR:
f611d0c3
MD
230 printf("ERROR: Visitor error\n");
231 abort();
f611d0c3
MD
232 }
233 printf(" ]");
f611d0c3
MD
234}
235
ba845af5
MD
236void tracer_print_array_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item)
237{
238 const struct side_type_description *elem_type = type_desc->u.side_array.elem_type;
239 uint32_t side_sav_len = type_desc->u.side_array.length;
240 void *p = item->u.side_array_fixint;
241 enum side_type side_type;
242 int i;
243
1e8256c9
MD
244 switch (item->type) {
245 case SIDE_TYPE_ARRAY_U8:
246 if (elem_type->type != SIDE_TYPE_U8)
247 goto type_error;
248 break;
249 case SIDE_TYPE_ARRAY_U16:
250 if (elem_type->type != SIDE_TYPE_U16)
251 goto type_error;
252 break;
253 case SIDE_TYPE_ARRAY_U32:
254 if (elem_type->type != SIDE_TYPE_U32)
255 goto type_error;
256 break;
257 case SIDE_TYPE_ARRAY_U64:
258 if (elem_type->type != SIDE_TYPE_U64)
259 goto type_error;
260 break;
261 case SIDE_TYPE_ARRAY_S8:
262 if (elem_type->type != SIDE_TYPE_S8)
263 goto type_error;
264 break;
265 case SIDE_TYPE_ARRAY_S16:
266 if (elem_type->type != SIDE_TYPE_S16)
267 goto type_error;
268 break;
269 case SIDE_TYPE_ARRAY_S32:
270 if (elem_type->type != SIDE_TYPE_S32)
271 goto type_error;
272 break;
273 case SIDE_TYPE_ARRAY_S64:
274 if (elem_type->type != SIDE_TYPE_S64)
275 goto type_error;
276 break;
277 default:
278 goto type_error;
ba845af5 279 }
1e8256c9 280 side_type = elem_type->type;
ba845af5 281
1533629f
MD
282 printf("[ ");
283 for (i = 0; i < side_sav_len; i++) {
284 struct side_arg_vec sav_elem = {
285 .type = side_type,
286 };
287
288 switch (side_type) {
289 case SIDE_TYPE_U8:
290 sav_elem.u.side_u8 = ((const uint8_t *) p)[i];
291 break;
292 case SIDE_TYPE_S8:
293 sav_elem.u.side_s8 = ((const int8_t *) p)[i];
294 break;
295 case SIDE_TYPE_U16:
296 sav_elem.u.side_u16 = ((const uint16_t *) p)[i];
297 break;
298 case SIDE_TYPE_S16:
299 sav_elem.u.side_s16 = ((const int16_t *) p)[i];
300 break;
301 case SIDE_TYPE_U32:
302 sav_elem.u.side_u32 = ((const uint32_t *) p)[i];
303 break;
304 case SIDE_TYPE_S32:
305 sav_elem.u.side_s32 = ((const int32_t *) p)[i];
306 break;
307 case SIDE_TYPE_U64:
308 sav_elem.u.side_u64 = ((const uint64_t *) p)[i];
309 break;
310 case SIDE_TYPE_S64:
311 sav_elem.u.side_s64 = ((const int64_t *) p)[i];
312 break;
313
314 default:
315 printf("ERROR: Unexpected type\n");
316 abort();
317 }
318
319 printf("%s", i ? ", " : "");
320 tracer_print_type(elem_type, &sav_elem);
321 }
322 printf(" ]");
323 return;
324
325type_error:
326 printf("ERROR: type mismatch\n");
327 abort();
328}
329
330void tracer_print_vla_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item)
331{
332 const struct side_type_description *elem_type = type_desc->u.side_vla.elem_type;
333 uint32_t side_sav_len = item->u.side_vla_fixint.length;
334 void *p = item->u.side_vla_fixint.p;
335 enum side_type side_type;
336 int i;
337
a2e2357e
MD
338 switch (item->type) {
339 case SIDE_TYPE_VLA_U8:
340 if (elem_type->type != SIDE_TYPE_U8)
1533629f 341 goto type_error;
a2e2357e
MD
342 break;
343 case SIDE_TYPE_VLA_U16:
344 if (elem_type->type != SIDE_TYPE_U16)
1533629f 345 goto type_error;
a2e2357e
MD
346 break;
347 case SIDE_TYPE_VLA_U32:
348 if (elem_type->type != SIDE_TYPE_U32)
349 goto type_error;
350 break;
351 case SIDE_TYPE_VLA_U64:
352 if (elem_type->type != SIDE_TYPE_U64)
353 goto type_error;
354 break;
355 case SIDE_TYPE_VLA_S8:
356 if (elem_type->type != SIDE_TYPE_S8)
357 goto type_error;
358 break;
359 case SIDE_TYPE_VLA_S16:
360 if (elem_type->type != SIDE_TYPE_S16)
361 goto type_error;
362 break;
363 case SIDE_TYPE_VLA_S32:
364 if (elem_type->type != SIDE_TYPE_S32)
365 goto type_error;
366 break;
367 case SIDE_TYPE_VLA_S64:
368 if (elem_type->type != SIDE_TYPE_S64)
369 goto type_error;
370 break;
371 default:
372 goto type_error;
1533629f 373 }
a2e2357e 374 side_type = elem_type->type;
1533629f 375
ba845af5
MD
376 printf("[ ");
377 for (i = 0; i < side_sav_len; i++) {
378 struct side_arg_vec sav_elem = {
379 .type = side_type,
380 };
381
382 switch (side_type) {
383 case SIDE_TYPE_U8:
384 sav_elem.u.side_u8 = ((const uint8_t *) p)[i];
385 break;
386 case SIDE_TYPE_S8:
387 sav_elem.u.side_s8 = ((const int8_t *) p)[i];
388 break;
389 case SIDE_TYPE_U16:
390 sav_elem.u.side_u16 = ((const uint16_t *) p)[i];
391 break;
392 case SIDE_TYPE_S16:
393 sav_elem.u.side_s16 = ((const int16_t *) p)[i];
394 break;
395 case SIDE_TYPE_U32:
396 sav_elem.u.side_u32 = ((const uint32_t *) p)[i];
397 break;
398 case SIDE_TYPE_S32:
399 sav_elem.u.side_s32 = ((const int32_t *) p)[i];
400 break;
401 case SIDE_TYPE_U64:
402 sav_elem.u.side_u64 = ((const uint64_t *) p)[i];
403 break;
404 case SIDE_TYPE_S64:
405 sav_elem.u.side_s64 = ((const int64_t *) p)[i];
406 break;
407
408 default:
409 printf("ERROR: Unexpected type\n");
410 abort();
411 }
412
413 printf("%s", i ? ", " : "");
414 tracer_print_type(elem_type, &sav_elem);
415 }
416 printf(" ]");
417 return;
418
419type_error:
420 printf("ERROR: type mismatch\n");
421 abort();
422}
423
a2e2357e 424static
c208889e 425void tracer_print_dynamic_struct(const struct side_arg_dynamic_event_struct *dynamic_struct)
a2e2357e 426{
c208889e
MD
427 const struct side_arg_dynamic_event_field *fields = dynamic_struct->fields;
428 uint32_t len = dynamic_struct->len;
465e5e7e
MD
429 int i;
430
431 printf("[ ");
432 for (i = 0; i < len; i++) {
433 printf("%s", i ? ", " : "");
434 printf("%s:: ", fields[i].field_name);
435 tracer_print_dynamic(&fields[i].elem);
436 }
437 printf(" ]");
a2e2357e
MD
438}
439
440static
c208889e 441void tracer_print_dynamic_struct_visitor(const struct side_arg_dynamic_vec *item)
a2e2357e
MD
442{
443 //TODO
444}
445
446static
447void tracer_print_dynamic_vla(const struct side_arg_dynamic_vec_vla *vla)
448{
449 const struct side_arg_dynamic_vec *sav = vla->sav;
450 uint32_t side_sav_len = vla->len;
451 int i;
452
453 printf("[ ");
454 for (i = 0; i < side_sav_len; i++) {
455 printf("%s", i ? ", " : "");
456 tracer_print_dynamic(&sav[i]);
457 }
458 printf(" ]");
459}
460
461static
462void tracer_print_dynamic_vla_visitor(const struct side_arg_dynamic_vec *item)
463{
464 //TODO
465}
466
467static
468void tracer_print_dynamic(const struct side_arg_dynamic_vec *item)
469{
1e8256c9 470 switch (item->dynamic_type) {
a2e2357e
MD
471 case SIDE_DYNAMIC_TYPE_NULL:
472 printf("<NULL TYPE>");
473 break;
474 case SIDE_DYNAMIC_TYPE_U8:
475 printf("%" PRIu8, item->u.side_u8);
476 break;
477 case SIDE_DYNAMIC_TYPE_U16:
478 printf("%" PRIu16, item->u.side_u16);
479 break;
480 case SIDE_DYNAMIC_TYPE_U32:
481 printf("%" PRIu32, item->u.side_u32);
482 break;
483 case SIDE_DYNAMIC_TYPE_U64:
484 printf("%" PRIu64, item->u.side_u64);
485 break;
486 case SIDE_DYNAMIC_TYPE_S8:
487 printf("%" PRId8, item->u.side_s8);
488 break;
489 case SIDE_DYNAMIC_TYPE_S16:
490 printf("%" PRId16, item->u.side_s16);
491 break;
492 case SIDE_DYNAMIC_TYPE_S32:
493 printf("%" PRId32, item->u.side_s32);
494 break;
495 case SIDE_DYNAMIC_TYPE_S64:
496 printf("%" PRId64, item->u.side_s64);
497 break;
498 case SIDE_DYNAMIC_TYPE_STRING:
499 printf("\"%s\"", item->u.string);
500 break;
c208889e
MD
501 case SIDE_DYNAMIC_TYPE_STRUCT:
502 tracer_print_dynamic_struct(item->u.side_dynamic_struct);
a2e2357e 503 break;
c208889e
MD
504 case SIDE_DYNAMIC_TYPE_STRUCT_VISITOR:
505 tracer_print_dynamic_struct_visitor(item);
a2e2357e
MD
506 break;
507 case SIDE_DYNAMIC_TYPE_VLA:
508 tracer_print_dynamic_vla(item->u.side_dynamic_vla);
509 break;
510 case SIDE_DYNAMIC_TYPE_VLA_VISITOR:
511 tracer_print_dynamic_vla_visitor(item);
512 break;
513 default:
514 printf("<UNKNOWN TYPE>");
515 abort();
516 }
517}
518
68f8cfbe
MD
519static
520void tracer_print_static_fields(const struct side_event_description *desc,
521 const struct side_arg_vec_description *sav_desc,
522 int *nr_items)
f611d0c3
MD
523{
524 const struct side_arg_vec *sav = sav_desc->sav;
525 uint32_t side_sav_len = sav_desc->len;
526 int i;
527
528 printf("provider: %s, event: %s, ", desc->provider_name, desc->event_name);
529 if (desc->nr_fields != side_sav_len) {
530 printf("ERROR: number of fields mismatch between description and arguments\n");
531 abort();
532 }
533 for (i = 0; i < side_sav_len; i++) {
534 printf("%s", i ? ", " : "");
535 tracer_print_field(&desc->fields[i], &sav[i]);
536 }
68f8cfbe
MD
537 if (nr_items)
538 *nr_items = i;
539}
540
541void tracer_call(const struct side_event_description *desc, const struct side_arg_vec_description *sav_desc)
542{
543 tracer_print_static_fields(desc, sav_desc, NULL);
f611d0c3
MD
544 printf("\n");
545}
19fa6aa2
MD
546
547void tracer_call_variadic(const struct side_event_description *desc,
548 const struct side_arg_vec_description *sav_desc,
549 const struct side_arg_dynamic_event_struct *var_struct)
550{
68f8cfbe
MD
551 uint32_t var_struct_len = var_struct->len;
552 int nr_fields = 0, i;
19fa6aa2 553
68f8cfbe
MD
554 tracer_print_static_fields(desc, sav_desc, &nr_fields);
555
556 for (i = 0; i < var_struct_len; i++, nr_fields++) {
557 printf("%s", nr_fields ? ", " : "");
558 printf("%s:: ", var_struct->fields[i].field_name);
559 tracer_print_dynamic(&var_struct->fields[i].elem);
19fa6aa2
MD
560 }
561 printf("\n");
562}
This page took 0.065403 seconds and 4 git commands to generate.