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