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
->before_elem_func
)
30 description_visitor
->before_elem_func(type_desc
, priv
);
31 side_visit_type(description_visitor
, type_desc
, priv
);
32 if (description_visitor
->after_elem_func
)
33 description_visitor
->after_elem_func(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
->before_field_func
)
40 description_visitor
->before_field_func(item_desc
, priv
);
41 side_visit_type(description_visitor
, &item_desc
->side_type
, priv
);
42 if (description_visitor
->after_field_func
)
43 description_visitor
->after_field_func(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
->before_option_func
)
50 description_visitor
->before_option_func(option_desc
, priv
);
51 side_visit_type(description_visitor
, &option_desc
->side_type
, priv
);
52 if (description_visitor
->after_option_func
)
53 description_visitor
->after_option_func(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
->before_enum_type_func
)
62 description_visitor
->before_enum_type_func(type_desc
, priv
);
63 side_visit_elem(description_visitor
, elem_type
, priv
);
64 if (description_visitor
->after_enum_type_func
)
65 description_visitor
->after_enum_type_func(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
);
73 if (description_visitor
->before_enum_bitmap_type_func
)
74 description_visitor
->before_enum_bitmap_type_func(type_desc
, priv
);
75 side_visit_elem(description_visitor
, elem_type
, priv
);
76 if (description_visitor
->after_enum_bitmap_type_func
)
77 description_visitor
->after_enum_bitmap_type_func(type_desc
, priv
);
81 void description_visitor_struct(const struct side_description_visitor
*description_visitor
, const struct side_type
*type_desc
, void *priv
)
83 const struct side_type_struct
*side_struct
= side_ptr_get(type_desc
->u
.side_struct
);
84 uint32_t i
, len
= side_struct
->nr_fields
;
86 if (description_visitor
->before_struct_type_func
)
87 description_visitor
->before_struct_type_func(side_struct
, priv
);
88 for (i
= 0; i
< len
; i
++)
89 side_visit_field(description_visitor
, &side_ptr_get(side_struct
->fields
)[i
], priv
);
90 if (description_visitor
->after_struct_type_func
)
91 description_visitor
->after_struct_type_func(side_struct
, priv
);
95 void description_visitor_variant(const struct side_description_visitor
*description_visitor
, const struct side_type
*type_desc
, void *priv
)
97 const struct side_type_variant
*side_type_variant
= side_ptr_get(type_desc
->u
.side_variant
);
98 const struct side_type
*selector_type
= &side_type_variant
->selector
;
99 uint32_t i
, len
= side_type_variant
->nr_options
;
101 switch (side_enum_get(selector_type
->type
)) {
114 fprintf(stderr
, "ERROR: Expecting integer variant selector type\n");
117 if (description_visitor
->before_variant_type_func
)
118 description_visitor
->before_variant_type_func(side_type_variant
, priv
);
119 for (i
= 0; i
< len
; i
++)
120 side_visit_option(description_visitor
, &side_ptr_get(side_type_variant
->options
)[i
], priv
);
121 if (description_visitor
->after_variant_type_func
)
122 description_visitor
->after_variant_type_func(side_type_variant
, priv
);
126 void description_visitor_array(const struct side_description_visitor
*description_visitor
, const struct side_type
*type_desc
, void *priv
)
128 if (description_visitor
->before_array_type_func
)
129 description_visitor
->before_array_type_func(&type_desc
->u
.side_array
, priv
);
130 side_visit_elem(description_visitor
, side_ptr_get(type_desc
->u
.side_array
.elem_type
), priv
);
131 if (description_visitor
->after_array_type_func
)
132 description_visitor
->after_array_type_func(&type_desc
->u
.side_array
, priv
);
136 void description_visitor_vla(const struct side_description_visitor
*description_visitor
, const struct side_type
*type_desc
, void *priv
)
138 if (description_visitor
->before_vla_type_func
)
139 description_visitor
->before_vla_type_func(&type_desc
->u
.side_vla
, priv
);
140 side_visit_elem(description_visitor
, side_ptr_get(type_desc
->u
.side_vla
.length_type
), priv
);
141 if (description_visitor
->after_length_vla_type_func
)
142 description_visitor
->after_length_vla_type_func(&type_desc
->u
.side_vla
, priv
);
143 side_visit_elem(description_visitor
, side_ptr_get(type_desc
->u
.side_vla
.elem_type
), priv
);
144 if (description_visitor
->after_element_vla_type_func
)
145 description_visitor
->after_element_vla_type_func(&type_desc
->u
.side_vla
, priv
);
149 void description_visitor_vla_visitor(const struct side_description_visitor
*description_visitor
, const struct side_type
*type_desc
, void *priv
)
151 if (description_visitor
->before_vla_visitor_type_func
)
152 description_visitor
->before_vla_visitor_type_func(side_ptr_get(type_desc
->u
.side_vla_visitor
), priv
);
153 side_visit_elem(description_visitor
, side_ptr_get(side_ptr_get(type_desc
->u
.side_vla_visitor
)->length_type
), priv
);
154 if (description_visitor
->after_length_vla_visitor_type_func
)
155 description_visitor
->after_length_vla_visitor_type_func(side_ptr_get(type_desc
->u
.side_vla_visitor
), priv
);
156 side_visit_elem(description_visitor
, side_ptr_get(side_ptr_get(type_desc
->u
.side_vla_visitor
)->elem_type
), priv
);
157 if (description_visitor
->after_element_vla_visitor_type_func
)
158 description_visitor
->after_element_vla_visitor_type_func(side_ptr_get(type_desc
->u
.side_vla_visitor
), priv
);
162 void visit_gather_field(const struct side_description_visitor
*description_visitor
, const struct side_event_field
*field
, void *priv
)
164 if (description_visitor
->before_field_func
)
165 description_visitor
->before_field_func(field
, priv
);
166 (void) visit_gather_type(description_visitor
, &field
->side_type
, priv
);
167 if (description_visitor
->after_field_func
)
168 description_visitor
->after_field_func(field
, priv
);
172 void description_visitor_gather_struct(const struct side_description_visitor
*description_visitor
, const struct side_type_gather
*type_gather
, void *priv
)
174 const struct side_type_gather_struct
*side_gather_struct
= &type_gather
->u
.side_struct
;
175 const struct side_type_struct
*side_struct
= side_ptr_get(side_gather_struct
->type
);
178 if (description_visitor
->before_gather_struct_type_func
)
179 description_visitor
->before_gather_struct_type_func(side_gather_struct
, priv
);
180 for (i
= 0; i
< side_struct
->nr_fields
; i
++)
181 visit_gather_field(description_visitor
, &side_ptr_get(side_struct
->fields
)[i
], priv
);
182 if (description_visitor
->after_gather_struct_type_func
)
183 description_visitor
->after_gather_struct_type_func(side_gather_struct
, priv
);
187 void description_visitor_gather_array(const struct side_description_visitor
*description_visitor
, const struct side_type_gather
*type_gather
, void *priv
)
189 const struct side_type_gather_array
*side_gather_array
= &type_gather
->u
.side_array
;
190 const struct side_type_array
*side_array
= &side_gather_array
->type
;
191 const struct side_type
*elem_type
= side_ptr_get(side_array
->elem_type
);
193 if (description_visitor
->before_gather_array_type_func
)
194 description_visitor
->before_gather_array_type_func(side_gather_array
, priv
);
195 switch (side_enum_get(elem_type
->type
)) {
196 case SIDE_TYPE_GATHER_VLA
:
197 fprintf(stderr
, "<gather VLA only supported within gather structures>\n");
202 visit_gather_elem(description_visitor
, elem_type
, priv
);
203 if (description_visitor
->after_gather_array_type_func
)
204 description_visitor
->after_gather_array_type_func(side_gather_array
, priv
);
208 void description_visitor_gather_vla(const struct side_description_visitor
*description_visitor
, const struct side_type_gather
*type_gather
, void *priv
)
210 const struct side_type_gather_vla
*side_gather_vla
= &type_gather
->u
.side_vla
;
211 const struct side_type_vla
*side_vla
= &side_gather_vla
->type
;
212 const struct side_type
*length_type
= side_ptr_get(side_gather_vla
->type
.length_type
);
213 const struct side_type
*elem_type
= side_ptr_get(side_vla
->elem_type
);
216 switch (side_enum_get(length_type
->type
)) {
217 case SIDE_TYPE_GATHER_INTEGER
:
220 fprintf(stderr
, "<gather VLA expects integer gather length type>\n");
223 switch (side_enum_get(elem_type
->type
)) {
224 case SIDE_TYPE_GATHER_VLA
:
225 fprintf(stderr
, "<gather VLA only supported within gather structures>\n");
230 if (description_visitor
->before_gather_vla_type_func
)
231 description_visitor
->before_gather_vla_type_func(side_gather_vla
, priv
);
232 visit_gather_elem(description_visitor
, length_type
, priv
);
233 if (description_visitor
->after_length_gather_vla_type_func
)
234 description_visitor
->after_length_gather_vla_type_func(side_gather_vla
, priv
);
235 visit_gather_elem(description_visitor
, elem_type
, priv
);
236 if (description_visitor
->after_element_gather_vla_type_func
)
237 description_visitor
->after_element_gather_vla_type_func(side_gather_vla
, priv
);
241 void description_visitor_gather_bool(const struct side_description_visitor
*description_visitor
, const struct side_type_gather
*type_gather
, void *priv
)
243 if (description_visitor
->gather_bool_type_func
)
244 description_visitor
->gather_bool_type_func(&type_gather
->u
.side_bool
, priv
);
248 void description_visitor_gather_byte(const struct side_description_visitor
*description_visitor
, const struct side_type_gather
*type_gather
, void *priv
)
250 if (description_visitor
->gather_byte_type_func
)
251 description_visitor
->gather_byte_type_func(&type_gather
->u
.side_byte
, priv
);
255 void description_visitor_gather_integer(const struct side_description_visitor
*description_visitor
, const struct side_type_gather
*type_gather
,
256 enum side_type_label integer_type
, void *priv
)
258 switch (integer_type
) {
259 case SIDE_TYPE_GATHER_INTEGER
:
260 if (description_visitor
->gather_integer_type_func
)
261 description_visitor
->gather_integer_type_func(&type_gather
->u
.side_integer
, priv
);
263 case SIDE_TYPE_GATHER_POINTER
:
264 if (description_visitor
->gather_pointer_type_func
)
265 description_visitor
->gather_pointer_type_func(&type_gather
->u
.side_integer
, priv
);
268 fprintf(stderr
, "Unexpected integer type\n");
274 void description_visitor_gather_float(const struct side_description_visitor
*description_visitor
, const struct side_type_gather
*type_gather
, void *priv
)
276 if (description_visitor
->gather_float_type_func
)
277 description_visitor
->gather_float_type_func(&type_gather
->u
.side_float
, priv
);
281 void description_visitor_gather_string(const struct side_description_visitor
*description_visitor
, const struct side_type_gather
*type_gather
, void *priv
)
284 if (description_visitor
->gather_string_type_func
)
285 description_visitor
->gather_string_type_func(&type_gather
->u
.side_string
, priv
);
289 void visit_gather_type(const struct side_description_visitor
*description_visitor
, const struct side_type
*type_desc
, void *priv
)
291 switch (side_enum_get(type_desc
->type
)) {
292 /* Gather basic types */
293 case SIDE_TYPE_GATHER_BOOL
:
294 description_visitor_gather_bool(description_visitor
, &type_desc
->u
.side_gather
, priv
);
296 case SIDE_TYPE_GATHER_INTEGER
:
297 description_visitor_gather_integer(description_visitor
, &type_desc
->u
.side_gather
, SIDE_TYPE_GATHER_INTEGER
, priv
);
299 case SIDE_TYPE_GATHER_BYTE
:
300 description_visitor_gather_byte(description_visitor
, &type_desc
->u
.side_gather
, priv
);
302 case SIDE_TYPE_GATHER_POINTER
:
303 description_visitor_gather_integer(description_visitor
, &type_desc
->u
.side_gather
, SIDE_TYPE_GATHER_POINTER
, priv
);
305 case SIDE_TYPE_GATHER_FLOAT
:
306 description_visitor_gather_float(description_visitor
, &type_desc
->u
.side_gather
, priv
);
308 case SIDE_TYPE_GATHER_STRING
:
309 description_visitor_gather_string(description_visitor
, &type_desc
->u
.side_gather
, priv
);
312 /* Gather enumeration types */
313 case SIDE_TYPE_GATHER_ENUM
:
314 description_visitor_gather_enum(description_visitor
, &type_desc
->u
.side_gather
, priv
);
317 /* Gather compound types */
318 case SIDE_TYPE_GATHER_STRUCT
:
319 description_visitor_gather_struct(description_visitor
, &type_desc
->u
.side_gather
, priv
);
321 case SIDE_TYPE_GATHER_ARRAY
:
322 description_visitor_gather_array(description_visitor
, &type_desc
->u
.side_gather
, priv
);
324 case SIDE_TYPE_GATHER_VLA
:
325 description_visitor_gather_vla(description_visitor
, &type_desc
->u
.side_gather
, priv
);
328 fprintf(stderr
, "<UNKNOWN GATHER TYPE>");
334 void visit_gather_elem(const struct side_description_visitor
*description_visitor
, const struct side_type
*type_desc
, void *priv
)
336 if (description_visitor
->before_elem_func
)
337 description_visitor
->before_elem_func(type_desc
, priv
);
338 visit_gather_type(description_visitor
, type_desc
, priv
);
339 if (description_visitor
->after_elem_func
)
340 description_visitor
->after_elem_func(type_desc
, priv
);
344 void description_visitor_gather_enum(const struct side_description_visitor
*description_visitor
, const struct side_type_gather
*type_gather
, void *priv
)
346 const struct side_type
*elem_type
= side_ptr_get(type_gather
->u
.side_enum
.elem_type
);
348 if (description_visitor
->before_gather_enum_type_func
)
349 description_visitor
->before_gather_enum_type_func(&type_gather
->u
.side_enum
, priv
);
350 side_visit_elem(description_visitor
, elem_type
, priv
);
351 if (description_visitor
->after_gather_enum_type_func
)
352 description_visitor
->after_gather_enum_type_func(&type_gather
->u
.side_enum
, priv
);
356 void side_visit_type(const struct side_description_visitor
*description_visitor
,
357 const struct side_type
*type_desc
, void *priv
)
359 enum side_type_label type
= side_enum_get(type_desc
->type
);
362 /* Stack-copy basic types */
364 if (description_visitor
->null_type_func
)
365 description_visitor
->null_type_func(type_desc
, priv
);
368 if (description_visitor
->bool_type_func
)
369 description_visitor
->bool_type_func(type_desc
, priv
);
371 case SIDE_TYPE_U8
: /* Fallthrough */
372 case SIDE_TYPE_U16
: /* Fallthrough */
373 case SIDE_TYPE_U32
: /* Fallthrough */
374 case SIDE_TYPE_U64
: /* Fallthrough */
375 case SIDE_TYPE_U128
: /* Fallthrough */
376 case SIDE_TYPE_S8
: /* Fallthrough */
377 case SIDE_TYPE_S16
: /* Fallthrough */
378 case SIDE_TYPE_S32
: /* Fallthrough */
379 case SIDE_TYPE_S64
: /* Fallthrough */
381 if (description_visitor
->integer_type_func
)
382 description_visitor
->integer_type_func(type_desc
, priv
);
385 if (description_visitor
->byte_type_func
)
386 description_visitor
->byte_type_func(type_desc
, priv
);
388 case SIDE_TYPE_POINTER
:
389 if (description_visitor
->pointer_type_func
)
390 description_visitor
->pointer_type_func(type_desc
, priv
);
392 case SIDE_TYPE_FLOAT_BINARY16
: /* Fallthrough */
393 case SIDE_TYPE_FLOAT_BINARY32
: /* Fallthrough */
394 case SIDE_TYPE_FLOAT_BINARY64
: /* Fallthrough */
395 case SIDE_TYPE_FLOAT_BINARY128
:
396 if (description_visitor
->float_type_func
)
397 description_visitor
->float_type_func(type_desc
, priv
);
399 case SIDE_TYPE_STRING_UTF8
: /* Fallthrough */
400 case SIDE_TYPE_STRING_UTF16
: /* Fallthrough */
401 case SIDE_TYPE_STRING_UTF32
:
402 if (description_visitor
->string_type_func
)
403 description_visitor
->string_type_func(type_desc
, priv
);
406 description_visitor_enum(description_visitor
, type_desc
, priv
);
408 case SIDE_TYPE_ENUM_BITMAP
:
409 description_visitor_enum_bitmap(description_visitor
, type_desc
, priv
);
412 /* Stack-copy compound types */
413 case SIDE_TYPE_STRUCT
:
414 description_visitor_struct(description_visitor
, type_desc
, priv
);
416 case SIDE_TYPE_VARIANT
:
417 description_visitor_variant(description_visitor
, type_desc
, priv
);
419 case SIDE_TYPE_ARRAY
:
420 description_visitor_array(description_visitor
, type_desc
, priv
);
423 description_visitor_vla(description_visitor
, type_desc
, priv
);
425 case SIDE_TYPE_VLA_VISITOR
:
426 description_visitor_vla_visitor(description_visitor
, type_desc
, priv
);
429 /* Gather basic types */
430 case SIDE_TYPE_GATHER_BOOL
:
431 description_visitor_gather_bool(description_visitor
, &type_desc
->u
.side_gather
, priv
);
433 case SIDE_TYPE_GATHER_INTEGER
:
434 description_visitor_gather_integer(description_visitor
, &type_desc
->u
.side_gather
, SIDE_TYPE_GATHER_INTEGER
, priv
);
436 case SIDE_TYPE_GATHER_BYTE
:
437 description_visitor_gather_byte(description_visitor
, &type_desc
->u
.side_gather
, priv
);
439 case SIDE_TYPE_GATHER_POINTER
:
440 description_visitor_gather_integer(description_visitor
, &type_desc
->u
.side_gather
, SIDE_TYPE_GATHER_POINTER
, priv
);
442 case SIDE_TYPE_GATHER_FLOAT
:
443 description_visitor_gather_float(description_visitor
, &type_desc
->u
.side_gather
, priv
);
445 case SIDE_TYPE_GATHER_STRING
:
446 description_visitor_gather_string(description_visitor
, &type_desc
->u
.side_gather
, priv
);
449 /* Gather compound type */
450 case SIDE_TYPE_GATHER_STRUCT
:
451 description_visitor_gather_struct(description_visitor
, &type_desc
->u
.side_gather
, priv
);
453 case SIDE_TYPE_GATHER_ARRAY
:
454 description_visitor_gather_array(description_visitor
, &type_desc
->u
.side_gather
, priv
);
456 case SIDE_TYPE_GATHER_VLA
:
457 description_visitor_gather_vla(description_visitor
, &type_desc
->u
.side_gather
, priv
);
460 /* Gather enumeration types */
461 case SIDE_TYPE_GATHER_ENUM
:
462 description_visitor_gather_enum(description_visitor
, &type_desc
->u
.side_gather
, priv
);
466 case SIDE_TYPE_DYNAMIC
:
467 if (description_visitor
->dynamic_type_func
)
468 description_visitor
->dynamic_type_func(type_desc
, priv
);
472 fprintf(stderr
, "<UNKNOWN TYPE>\n");
477 void description_visitor_event(const struct side_description_visitor
*description_visitor
,
478 const struct side_event_description
*desc
, void *priv
)
480 uint32_t i
, len
= desc
->nr_fields
;
482 if (description_visitor
->before_event_func
)
483 description_visitor
->before_event_func(desc
, priv
);
485 if (description_visitor
->before_static_fields_func
)
486 description_visitor
->before_static_fields_func(desc
, priv
);
487 for (i
= 0; i
< len
; i
++)
488 side_visit_field(description_visitor
, &side_ptr_get(desc
->fields
)[i
], priv
);
489 if (description_visitor
->after_static_fields_func
)
490 description_visitor
->after_static_fields_func(desc
, priv
);
492 if (description_visitor
->after_event_func
)
493 description_visitor
->after_event_func(desc
, priv
);