1 // SPDX-License-Identifier: MIT
3 * Copyright 2022-2024 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 #include "visit-description.h"
11 void side_visit_type(const struct side_description_visitor
*description_visitor
,
12 const struct side_type
*type_desc
, void *priv
);
15 void visit_gather_type(const struct side_description_visitor
*description_visitor
,
16 const struct side_type
*type_desc
, void *priv
);
19 void visit_gather_elem(const struct side_description_visitor
*description_visitor
,
20 const struct side_type
*type_desc
, void *priv
);
23 void description_visitor_gather_enum(const struct side_description_visitor
*description_visitor
,
24 const struct side_type_gather
*type_gather
, void *priv
);
27 void side_visit_elem(const struct side_description_visitor
*description_visitor
, const struct side_type
*type_desc
, void *priv
)
29 if (description_visitor
->elem_func
)
30 description_visitor
->elem_func(SIDE_DESCRIPTION_VISITOR_BEFORE
, type_desc
, priv
);
31 side_visit_type(description_visitor
, type_desc
, priv
);
32 if (description_visitor
->elem_func
)
33 description_visitor
->elem_func(SIDE_DESCRIPTION_VISITOR_AFTER
, type_desc
, priv
);
37 void side_visit_field(const struct side_description_visitor
*description_visitor
, const struct side_event_field
*item_desc
, void *priv
)
39 if (description_visitor
->field_func
)
40 description_visitor
->field_func(SIDE_DESCRIPTION_VISITOR_BEFORE
, item_desc
, priv
);
41 side_visit_type(description_visitor
, &item_desc
->side_type
, priv
);
42 if (description_visitor
->field_func
)
43 description_visitor
->field_func(SIDE_DESCRIPTION_VISITOR_AFTER
, item_desc
, priv
);
47 void side_visit_option(const struct side_description_visitor
*description_visitor
, const struct side_variant_option
*option_desc
, void *priv
)
49 if (description_visitor
->option_func
)
50 description_visitor
->option_func(SIDE_DESCRIPTION_VISITOR_BEFORE
, option_desc
, priv
);
51 side_visit_type(description_visitor
, &option_desc
->side_type
, priv
);
52 if (description_visitor
->option_func
)
53 description_visitor
->option_func(SIDE_DESCRIPTION_VISITOR_AFTER
, option_desc
, priv
);
57 void description_visitor_enum(const struct side_description_visitor
*description_visitor
, const struct side_type
*type_desc
, void *priv
)
59 const struct side_type
*elem_type
= side_ptr_get(type_desc
->u
.side_enum
.elem_type
);
61 if (description_visitor
->enum_type_func
)
62 description_visitor
->enum_type_func(SIDE_DESCRIPTION_VISITOR_BEFORE
, type_desc
, priv
);
63 side_visit_elem(description_visitor
, elem_type
, priv
);
64 if (description_visitor
->enum_type_func
)
65 description_visitor
->enum_type_func(SIDE_DESCRIPTION_VISITOR_AFTER
, type_desc
, priv
);
69 void description_visitor_enum_bitmap(const struct side_description_visitor
*description_visitor
, const struct side_type
*type_desc
, void *priv
)
71 const struct side_type
*elem_type
= side_ptr_get(type_desc
->u
.side_enum_bitmap
.elem_type
);
74 if (description_visitor
->enum_bitmap_type_func
)
75 description_visitor
->enum_bitmap_type_func(SIDE_DESCRIPTION_VISITOR_BEFORE
, type_desc
, priv
);
76 side_visit_elem(description_visitor
, elem_type
, priv
);
77 if (description_visitor
->enum_bitmap_type_func
)
78 description_visitor
->enum_bitmap_type_func(SIDE_DESCRIPTION_VISITOR_AFTER
, type_desc
, priv
);
82 void description_visitor_struct(const struct side_description_visitor
*description_visitor
, const struct side_type
*type_desc
, void *priv
)
84 const struct side_type_struct
*side_struct
= side_ptr_get(type_desc
->u
.side_struct
);
85 uint32_t i
, len
= side_struct
->nr_fields
;
87 if (description_visitor
->struct_type_func
)
88 description_visitor
->struct_type_func(SIDE_DESCRIPTION_VISITOR_BEFORE
, side_struct
, priv
);
89 for (i
= 0; i
< len
; i
++)
90 side_visit_field(description_visitor
, &side_ptr_get(side_struct
->fields
)[i
], priv
);
91 if (description_visitor
->struct_type_func
)
92 description_visitor
->struct_type_func(SIDE_DESCRIPTION_VISITOR_AFTER
, side_struct
, priv
);
96 void description_visitor_variant(const struct side_description_visitor
*description_visitor
, const struct side_type
*type_desc
, void *priv
)
98 const struct side_type_variant
*side_type_variant
= side_ptr_get(type_desc
->u
.side_variant
);
99 const struct side_type
*selector_type
= &side_type_variant
->selector
;
100 uint32_t i
, len
= side_type_variant
->nr_options
;
102 switch (side_enum_get(selector_type
->type
)) {
115 fprintf(stderr
, "ERROR: Expecting integer variant selector type\n");
118 if (description_visitor
->variant_type_func
)
119 description_visitor
->variant_type_func(SIDE_DESCRIPTION_VISITOR_BEFORE
, side_type_variant
, priv
);
120 for (i
= 0; i
< len
; i
++)
121 side_visit_option(description_visitor
, &side_ptr_get(side_type_variant
->options
)[i
], priv
);
122 if (description_visitor
->variant_type_func
)
123 description_visitor
->variant_type_func(SIDE_DESCRIPTION_VISITOR_AFTER
, side_type_variant
, priv
);
127 void description_visitor_array(const struct side_description_visitor
*description_visitor
, const struct side_type
*type_desc
, void *priv
)
129 if (description_visitor
->array_type_func
)
130 description_visitor
->array_type_func(SIDE_DESCRIPTION_VISITOR_BEFORE
, &type_desc
->u
.side_array
, priv
);
131 side_visit_elem(description_visitor
, side_ptr_get(type_desc
->u
.side_array
.elem_type
), priv
);
132 if (description_visitor
->array_type_func
)
133 description_visitor
->array_type_func(SIDE_DESCRIPTION_VISITOR_AFTER
, &type_desc
->u
.side_array
, priv
);
137 void description_visitor_vla(const struct side_description_visitor
*description_visitor
, const struct side_type
*type_desc
, void *priv
)
139 if (description_visitor
->vla_type_func
)
140 description_visitor
->vla_type_func(SIDE_DESCRIPTION_VISITOR_VLA_BEFORE
, &type_desc
->u
.side_vla
, priv
);
141 side_visit_elem(description_visitor
, side_ptr_get(type_desc
->u
.side_vla
.length_type
), priv
);
142 if (description_visitor
->vla_type_func
)
143 description_visitor
->vla_type_func(SIDE_DESCRIPTION_VISITOR_VLA_AFTER_LENGTH
, &type_desc
->u
.side_vla
, priv
);
144 side_visit_elem(description_visitor
, side_ptr_get(type_desc
->u
.side_vla
.elem_type
), priv
);
145 if (description_visitor
->vla_type_func
)
146 description_visitor
->vla_type_func(SIDE_DESCRIPTION_VISITOR_VLA_AFTER_ELEMENT
, &type_desc
->u
.side_vla
, priv
);
150 void description_visitor_vla_visitor(const struct side_description_visitor
*description_visitor
, const struct side_type
*type_desc
, void *priv
)
152 if (description_visitor
->vla_visitor_type_func
)
153 description_visitor
->vla_visitor_type_func(SIDE_DESCRIPTION_VISITOR_VLA_BEFORE
, side_ptr_get(type_desc
->u
.side_vla_visitor
), priv
);
154 side_visit_elem(description_visitor
, side_ptr_get(side_ptr_get(type_desc
->u
.side_vla_visitor
)->length_type
), priv
);
155 if (description_visitor
->vla_visitor_type_func
)
156 description_visitor
->vla_visitor_type_func(SIDE_DESCRIPTION_VISITOR_VLA_AFTER_LENGTH
, side_ptr_get(type_desc
->u
.side_vla_visitor
), priv
);
157 side_visit_elem(description_visitor
, side_ptr_get(side_ptr_get(type_desc
->u
.side_vla_visitor
)->elem_type
), priv
);
158 if (description_visitor
->vla_visitor_type_func
)
159 description_visitor
->vla_visitor_type_func(SIDE_DESCRIPTION_VISITOR_VLA_AFTER_ELEMENT
, side_ptr_get(type_desc
->u
.side_vla_visitor
), priv
);
163 void visit_gather_field(const struct side_description_visitor
*description_visitor
, const struct side_event_field
*field
, void *priv
)
165 if (description_visitor
->field_func
)
166 description_visitor
->field_func(SIDE_DESCRIPTION_VISITOR_BEFORE
, field
, priv
);
167 (void) visit_gather_type(description_visitor
, &field
->side_type
, priv
);
168 if (description_visitor
->field_func
)
169 description_visitor
->field_func(SIDE_DESCRIPTION_VISITOR_AFTER
, field
, priv
);
173 void description_visitor_gather_struct(const struct side_description_visitor
*description_visitor
, const struct side_type_gather
*type_gather
, void *priv
)
175 const struct side_type_gather_struct
*side_gather_struct
= &type_gather
->u
.side_struct
;
176 const struct side_type_struct
*side_struct
= side_ptr_get(side_gather_struct
->type
);
179 if (description_visitor
->gather_struct_type_func
)
180 description_visitor
->gather_struct_type_func(SIDE_DESCRIPTION_VISITOR_BEFORE
, side_gather_struct
, priv
);
181 for (i
= 0; i
< side_struct
->nr_fields
; i
++)
182 visit_gather_field(description_visitor
, &side_ptr_get(side_struct
->fields
)[i
], priv
);
183 if (description_visitor
->gather_struct_type_func
)
184 description_visitor
->gather_struct_type_func(SIDE_DESCRIPTION_VISITOR_AFTER
, side_gather_struct
, priv
);
188 void description_visitor_gather_array(const struct side_description_visitor
*description_visitor
, const struct side_type_gather
*type_gather
, void *priv
)
190 const struct side_type_gather_array
*side_gather_array
= &type_gather
->u
.side_array
;
191 const struct side_type_array
*side_array
= &side_gather_array
->type
;
192 const struct side_type
*elem_type
= side_ptr_get(side_array
->elem_type
);
194 if (description_visitor
->gather_array_type_func
)
195 description_visitor
->gather_array_type_func(SIDE_DESCRIPTION_VISITOR_BEFORE
, side_gather_array
, priv
);
196 switch (side_enum_get(elem_type
->type
)) {
197 case SIDE_TYPE_GATHER_VLA
:
198 fprintf(stderr
, "<gather VLA only supported within gather structures>\n");
203 visit_gather_elem(description_visitor
, elem_type
, priv
);
204 if (description_visitor
->gather_array_type_func
)
205 description_visitor
->gather_array_type_func(SIDE_DESCRIPTION_VISITOR_AFTER
, side_gather_array
, priv
);
209 void description_visitor_gather_vla(const struct side_description_visitor
*description_visitor
, const struct side_type_gather
*type_gather
, void *priv
)
211 const struct side_type_gather_vla
*side_gather_vla
= &type_gather
->u
.side_vla
;
212 const struct side_type_vla
*side_vla
= &side_gather_vla
->type
;
213 const struct side_type
*length_type
= side_ptr_get(side_gather_vla
->type
.length_type
);
214 const struct side_type
*elem_type
= side_ptr_get(side_vla
->elem_type
);
217 switch (side_enum_get(length_type
->type
)) {
218 case SIDE_TYPE_GATHER_INTEGER
:
221 fprintf(stderr
, "<gather VLA expects integer gather length type>\n");
224 switch (side_enum_get(elem_type
->type
)) {
225 case SIDE_TYPE_GATHER_VLA
:
226 fprintf(stderr
, "<gather VLA only supported within gather structures>\n");
231 if (description_visitor
->gather_vla_type_func
)
232 description_visitor
->gather_vla_type_func(SIDE_DESCRIPTION_VISITOR_VLA_BEFORE
, side_gather_vla
, priv
);
233 visit_gather_elem(description_visitor
, length_type
, priv
);
234 if (description_visitor
->gather_vla_type_func
)
235 description_visitor
->gather_vla_type_func(SIDE_DESCRIPTION_VISITOR_VLA_AFTER_LENGTH
, side_gather_vla
, priv
);
236 visit_gather_elem(description_visitor
, elem_type
, priv
);
237 if (description_visitor
->gather_vla_type_func
)
238 description_visitor
->gather_vla_type_func(SIDE_DESCRIPTION_VISITOR_VLA_AFTER_ELEMENT
, side_gather_vla
, priv
);
242 void description_visitor_gather_bool(const struct side_description_visitor
*description_visitor
, const struct side_type_gather
*type_gather
, void *priv
)
244 if (description_visitor
->gather_bool_type_func
)
245 description_visitor
->gather_bool_type_func(&type_gather
->u
.side_bool
, priv
);
249 void description_visitor_gather_byte(const struct side_description_visitor
*description_visitor
, const struct side_type_gather
*type_gather
, void *priv
)
251 if (description_visitor
->gather_byte_type_func
)
252 description_visitor
->gather_byte_type_func(&type_gather
->u
.side_byte
, priv
);
256 void description_visitor_gather_integer(const struct side_description_visitor
*description_visitor
, const struct side_type_gather
*type_gather
,
257 enum side_type_label integer_type
, void *priv
)
259 switch (integer_type
) {
260 case SIDE_TYPE_GATHER_INTEGER
:
261 if (description_visitor
->gather_integer_type_func
)
262 description_visitor
->gather_integer_type_func(&type_gather
->u
.side_integer
, priv
);
264 case SIDE_TYPE_GATHER_POINTER
:
265 if (description_visitor
->gather_pointer_type_func
)
266 description_visitor
->gather_pointer_type_func(&type_gather
->u
.side_integer
, priv
);
269 fprintf(stderr
, "Unexpected integer type\n");
275 void description_visitor_gather_float(const struct side_description_visitor
*description_visitor
, const struct side_type_gather
*type_gather
, void *priv
)
277 if (description_visitor
->gather_float_type_func
)
278 description_visitor
->gather_float_type_func(&type_gather
->u
.side_float
, priv
);
282 void description_visitor_gather_string(const struct side_description_visitor
*description_visitor
, const struct side_type_gather
*type_gather
, void *priv
)
285 if (description_visitor
->gather_string_type_func
)
286 description_visitor
->gather_string_type_func(&type_gather
->u
.side_string
, priv
);
290 void visit_gather_type(const struct side_description_visitor
*description_visitor
, const struct side_type
*type_desc
, void *priv
)
292 switch (side_enum_get(type_desc
->type
)) {
293 /* Gather basic types */
294 case SIDE_TYPE_GATHER_BOOL
:
295 description_visitor_gather_bool(description_visitor
, &type_desc
->u
.side_gather
, priv
);
297 case SIDE_TYPE_GATHER_INTEGER
:
298 description_visitor_gather_integer(description_visitor
, &type_desc
->u
.side_gather
, SIDE_TYPE_GATHER_INTEGER
, priv
);
300 case SIDE_TYPE_GATHER_BYTE
:
301 description_visitor_gather_byte(description_visitor
, &type_desc
->u
.side_gather
, priv
);
303 case SIDE_TYPE_GATHER_POINTER
:
304 description_visitor_gather_integer(description_visitor
, &type_desc
->u
.side_gather
, SIDE_TYPE_GATHER_POINTER
, priv
);
306 case SIDE_TYPE_GATHER_FLOAT
:
307 description_visitor_gather_float(description_visitor
, &type_desc
->u
.side_gather
, priv
);
309 case SIDE_TYPE_GATHER_STRING
:
310 description_visitor_gather_string(description_visitor
, &type_desc
->u
.side_gather
, priv
);
313 /* Gather enumeration types */
314 case SIDE_TYPE_GATHER_ENUM
:
315 description_visitor_gather_enum(description_visitor
, &type_desc
->u
.side_gather
, priv
);
318 /* Gather compound types */
319 case SIDE_TYPE_GATHER_STRUCT
:
320 description_visitor_gather_struct(description_visitor
, &type_desc
->u
.side_gather
, priv
);
322 case SIDE_TYPE_GATHER_ARRAY
:
323 description_visitor_gather_array(description_visitor
, &type_desc
->u
.side_gather
, priv
);
325 case SIDE_TYPE_GATHER_VLA
:
326 description_visitor_gather_vla(description_visitor
, &type_desc
->u
.side_gather
, priv
);
329 fprintf(stderr
, "<UNKNOWN GATHER TYPE>");
335 void visit_gather_elem(const struct side_description_visitor
*description_visitor
, const struct side_type
*type_desc
, void *priv
)
337 if (description_visitor
->elem_func
)
338 description_visitor
->elem_func(SIDE_DESCRIPTION_VISITOR_BEFORE
, type_desc
, priv
);
339 visit_gather_type(description_visitor
, type_desc
, priv
);
340 if (description_visitor
->elem_func
)
341 description_visitor
->elem_func(SIDE_DESCRIPTION_VISITOR_AFTER
, type_desc
, priv
);
345 void description_visitor_gather_enum(const struct side_description_visitor
*description_visitor
, const struct side_type_gather
*type_gather
, void *priv
)
347 const struct side_type
*elem_type
= side_ptr_get(type_gather
->u
.side_enum
.elem_type
);
349 if (description_visitor
->gather_enum_type_func
)
350 description_visitor
->gather_enum_type_func(SIDE_DESCRIPTION_VISITOR_BEFORE
, &type_gather
->u
.side_enum
, priv
);
351 side_visit_elem(description_visitor
, elem_type
, priv
);
352 if (description_visitor
->gather_enum_type_func
)
353 description_visitor
->gather_enum_type_func(SIDE_DESCRIPTION_VISITOR_AFTER
, &type_gather
->u
.side_enum
, priv
);
357 void side_visit_type(const struct side_description_visitor
*description_visitor
,
358 const struct side_type
*type_desc
, void *priv
)
360 enum side_type_label type
= side_enum_get(type_desc
->type
);
363 /* Stack-copy basic types */
365 if (description_visitor
->null_type_func
)
366 description_visitor
->null_type_func(type_desc
, priv
);
369 if (description_visitor
->bool_type_func
)
370 description_visitor
->bool_type_func(type_desc
, priv
);
372 case SIDE_TYPE_U8
: /* Fallthrough */
373 case SIDE_TYPE_U16
: /* Fallthrough */
374 case SIDE_TYPE_U32
: /* Fallthrough */
375 case SIDE_TYPE_U64
: /* Fallthrough */
376 case SIDE_TYPE_U128
: /* Fallthrough */
377 case SIDE_TYPE_S8
: /* Fallthrough */
378 case SIDE_TYPE_S16
: /* Fallthrough */
379 case SIDE_TYPE_S32
: /* Fallthrough */
380 case SIDE_TYPE_S64
: /* Fallthrough */
382 if (description_visitor
->integer_type_func
)
383 description_visitor
->integer_type_func(type_desc
, priv
);
386 if (description_visitor
->byte_type_func
)
387 description_visitor
->byte_type_func(type_desc
, priv
);
389 case SIDE_TYPE_POINTER
:
390 if (description_visitor
->pointer_type_func
)
391 description_visitor
->pointer_type_func(type_desc
, priv
);
393 case SIDE_TYPE_FLOAT_BINARY16
: /* Fallthrough */
394 case SIDE_TYPE_FLOAT_BINARY32
: /* Fallthrough */
395 case SIDE_TYPE_FLOAT_BINARY64
: /* Fallthrough */
396 case SIDE_TYPE_FLOAT_BINARY128
:
397 if (description_visitor
->float_type_func
)
398 description_visitor
->float_type_func(type_desc
, priv
);
400 case SIDE_TYPE_STRING_UTF8
: /* Fallthrough */
401 case SIDE_TYPE_STRING_UTF16
: /* Fallthrough */
402 case SIDE_TYPE_STRING_UTF32
:
403 if (description_visitor
->string_type_func
)
404 description_visitor
->string_type_func(type_desc
, priv
);
407 description_visitor_enum(description_visitor
, type_desc
, priv
);
409 case SIDE_TYPE_ENUM_BITMAP
:
410 description_visitor_enum_bitmap(description_visitor
, type_desc
, priv
);
413 /* Stack-copy compound types */
414 case SIDE_TYPE_STRUCT
:
415 description_visitor_struct(description_visitor
, type_desc
, priv
);
417 case SIDE_TYPE_VARIANT
:
418 description_visitor_variant(description_visitor
, type_desc
, priv
);
420 case SIDE_TYPE_ARRAY
:
421 description_visitor_array(description_visitor
, type_desc
, priv
);
424 description_visitor_vla(description_visitor
, type_desc
, priv
);
426 case SIDE_TYPE_VLA_VISITOR
:
427 description_visitor_vla_visitor(description_visitor
, type_desc
, priv
);
430 /* Gather basic types */
431 case SIDE_TYPE_GATHER_BOOL
:
432 description_visitor_gather_bool(description_visitor
, &type_desc
->u
.side_gather
, priv
);
434 case SIDE_TYPE_GATHER_INTEGER
:
435 description_visitor_gather_integer(description_visitor
, &type_desc
->u
.side_gather
, SIDE_TYPE_GATHER_INTEGER
, priv
);
437 case SIDE_TYPE_GATHER_BYTE
:
438 description_visitor_gather_byte(description_visitor
, &type_desc
->u
.side_gather
, priv
);
440 case SIDE_TYPE_GATHER_POINTER
:
441 description_visitor_gather_integer(description_visitor
, &type_desc
->u
.side_gather
, SIDE_TYPE_GATHER_POINTER
, priv
);
443 case SIDE_TYPE_GATHER_FLOAT
:
444 description_visitor_gather_float(description_visitor
, &type_desc
->u
.side_gather
, priv
);
446 case SIDE_TYPE_GATHER_STRING
:
447 description_visitor_gather_string(description_visitor
, &type_desc
->u
.side_gather
, priv
);
450 /* Gather compound type */
451 case SIDE_TYPE_GATHER_STRUCT
:
452 description_visitor_gather_struct(description_visitor
, &type_desc
->u
.side_gather
, priv
);
454 case SIDE_TYPE_GATHER_ARRAY
:
455 description_visitor_gather_array(description_visitor
, &type_desc
->u
.side_gather
, priv
);
457 case SIDE_TYPE_GATHER_VLA
:
458 description_visitor_gather_vla(description_visitor
, &type_desc
->u
.side_gather
, priv
);
461 /* Gather enumeration types */
462 case SIDE_TYPE_GATHER_ENUM
:
463 description_visitor_gather_enum(description_visitor
, &type_desc
->u
.side_gather
, priv
);
467 case SIDE_TYPE_DYNAMIC
:
468 if (description_visitor
->dynamic_type_func
)
469 description_visitor
->dynamic_type_func(type_desc
, priv
);
473 fprintf(stderr
, "<UNKNOWN TYPE>\n");
478 void description_visitor_event(const struct side_description_visitor
*description_visitor
,
479 const struct side_event_description
*desc
, void *priv
)
481 uint32_t i
, len
= desc
->nr_fields
;
483 if (description_visitor
->event_func
)
484 description_visitor
->event_func(SIDE_DESCRIPTION_VISITOR_BEFORE
, desc
, priv
);
486 if (description_visitor
->static_fields_func
)
487 description_visitor
->static_fields_func(SIDE_DESCRIPTION_VISITOR_BEFORE
, desc
, priv
);
488 for (i
= 0; i
< len
; i
++)
489 side_visit_field(description_visitor
, &side_ptr_get(desc
->fields
)[i
], priv
);
490 if (description_visitor
->static_fields_func
)
491 description_visitor
->static_fields_func(SIDE_DESCRIPTION_VISITOR_AFTER
, desc
, priv
);
493 if (description_visitor
->event_func
)
494 description_visitor
->event_func(SIDE_DESCRIPTION_VISITOR_AFTER
, desc
, priv
);