Introduce event/type description visitor
[libside.git] / src / visit-description.c
CommitLineData
f0619c77
MD
1// SPDX-License-Identifier: MIT
2/*
3 * Copyright 2022-2024 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
4 */
5
6#include <string.h>
7
8#include "visit-description.h"
9
10static
11void side_visit_type(const struct side_description_visitor *description_visitor,
12 const struct side_type *type_desc, void *priv);
13
14static
15void visit_gather_type(const struct side_description_visitor *description_visitor,
16 const struct side_type *type_desc, void *priv);
17
18static
19void visit_gather_elem(const struct side_description_visitor *description_visitor,
20 const struct side_type *type_desc, void *priv);
21
22static
23void description_visitor_gather_enum(const struct side_description_visitor *description_visitor,
24 const struct side_type_gather *type_gather, void *priv);
25
26static
27void side_visit_elem(const struct side_description_visitor *description_visitor, const struct side_type *type_desc, void *priv)
28{
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);
34}
35
36static
37void side_visit_field(const struct side_description_visitor *description_visitor, const struct side_event_field *item_desc, void *priv)
38{
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);
44}
45
46static
47void side_visit_option(const struct side_description_visitor *description_visitor, const struct side_variant_option *option_desc, void *priv)
48{
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);
54}
55
56static
57void description_visitor_enum(const struct side_description_visitor *description_visitor, const struct side_type *type_desc, void *priv)
58{
59 const struct side_type *elem_type = side_ptr_get(type_desc->u.side_enum.elem_type);
60
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);
66}
67
68static
69void description_visitor_enum_bitmap(const struct side_description_visitor *description_visitor, const struct side_type *type_desc, void *priv)
70{
71 const struct side_type *elem_type = side_ptr_get(type_desc->u.side_enum_bitmap.elem_type);
72
73
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);
79}
80
81static
82void description_visitor_struct(const struct side_description_visitor *description_visitor, const struct side_type *type_desc, void *priv)
83{
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;
86
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);
93}
94
95static
96void description_visitor_variant(const struct side_description_visitor *description_visitor, const struct side_type *type_desc, void *priv)
97{
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;
101
102 switch (side_enum_get(selector_type->type)) {
103 case SIDE_TYPE_U8:
104 case SIDE_TYPE_U16:
105 case SIDE_TYPE_U32:
106 case SIDE_TYPE_U64:
107 case SIDE_TYPE_U128:
108 case SIDE_TYPE_S8:
109 case SIDE_TYPE_S16:
110 case SIDE_TYPE_S32:
111 case SIDE_TYPE_S64:
112 case SIDE_TYPE_S128:
113 break;
114 default:
115 fprintf(stderr, "ERROR: Expecting integer variant selector type\n");
116 abort();
117 }
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);
124}
125
126static
127void description_visitor_array(const struct side_description_visitor *description_visitor, const struct side_type *type_desc, void *priv)
128{
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);
134}
135
136static
137void description_visitor_vla(const struct side_description_visitor *description_visitor, const struct side_type *type_desc, void *priv)
138{
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);
147}
148
149static
150void description_visitor_vla_visitor(const struct side_description_visitor *description_visitor, const struct side_type *type_desc, void *priv)
151{
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);
160}
161
162static
163void visit_gather_field(const struct side_description_visitor *description_visitor, const struct side_event_field *field, void *priv)
164{
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);
170}
171
172static
173void description_visitor_gather_struct(const struct side_description_visitor *description_visitor, const struct side_type_gather *type_gather, void *priv)
174{
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);
177 uint32_t i;
178
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);
185}
186
187static
188void description_visitor_gather_array(const struct side_description_visitor *description_visitor, const struct side_type_gather *type_gather, void *priv)
189{
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);
193
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");
199 abort();
200 default:
201 break;
202 }
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);
206}
207
208static
209void description_visitor_gather_vla(const struct side_description_visitor *description_visitor, const struct side_type_gather *type_gather, void *priv)
210{
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);
215
216 /* Access length */
217 switch (side_enum_get(length_type->type)) {
218 case SIDE_TYPE_GATHER_INTEGER:
219 break;
220 default:
221 fprintf(stderr, "<gather VLA expects integer gather length type>\n");
222 abort();
223 }
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");
227 abort();
228 default:
229 break;
230 }
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);
239}
240
241static
242void description_visitor_gather_bool(const struct side_description_visitor *description_visitor, const struct side_type_gather *type_gather, void *priv)
243{
244 if (description_visitor->gather_bool_type_func)
245 description_visitor->gather_bool_type_func(&type_gather->u.side_bool, priv);
246}
247
248static
249void description_visitor_gather_byte(const struct side_description_visitor *description_visitor, const struct side_type_gather *type_gather, void *priv)
250{
251 if (description_visitor->gather_byte_type_func)
252 description_visitor->gather_byte_type_func(&type_gather->u.side_byte, priv);
253}
254
255static
256void 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)
258{
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);
263 break;
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);
267 break;
268 default:
269 fprintf(stderr, "Unexpected integer type\n");
270 abort();
271 }
272}
273
274static
275void description_visitor_gather_float(const struct side_description_visitor *description_visitor, const struct side_type_gather *type_gather, void *priv)
276{
277 if (description_visitor->gather_float_type_func)
278 description_visitor->gather_float_type_func(&type_gather->u.side_float, priv);
279}
280
281static
282void description_visitor_gather_string(const struct side_description_visitor *description_visitor, const struct side_type_gather *type_gather, void *priv)
283{
284
285 if (description_visitor->gather_string_type_func)
286 description_visitor->gather_string_type_func(&type_gather->u.side_string, priv);
287}
288
289static
290void visit_gather_type(const struct side_description_visitor *description_visitor, const struct side_type *type_desc, void *priv)
291{
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);
296 break;
297 case SIDE_TYPE_GATHER_INTEGER:
298 description_visitor_gather_integer(description_visitor, &type_desc->u.side_gather, SIDE_TYPE_GATHER_INTEGER, priv);
299 break;
300 case SIDE_TYPE_GATHER_BYTE:
301 description_visitor_gather_byte(description_visitor, &type_desc->u.side_gather, priv);
302 break;
303 case SIDE_TYPE_GATHER_POINTER:
304 description_visitor_gather_integer(description_visitor, &type_desc->u.side_gather, SIDE_TYPE_GATHER_POINTER, priv);
305 break;
306 case SIDE_TYPE_GATHER_FLOAT:
307 description_visitor_gather_float(description_visitor, &type_desc->u.side_gather, priv);
308 break;
309 case SIDE_TYPE_GATHER_STRING:
310 description_visitor_gather_string(description_visitor, &type_desc->u.side_gather, priv);
311 break;
312
313 /* Gather enumeration types */
314 case SIDE_TYPE_GATHER_ENUM:
315 description_visitor_gather_enum(description_visitor, &type_desc->u.side_gather, priv);
316 break;
317
318 /* Gather compound types */
319 case SIDE_TYPE_GATHER_STRUCT:
320 description_visitor_gather_struct(description_visitor, &type_desc->u.side_gather, priv);
321 break;
322 case SIDE_TYPE_GATHER_ARRAY:
323 description_visitor_gather_array(description_visitor, &type_desc->u.side_gather, priv);
324 break;
325 case SIDE_TYPE_GATHER_VLA:
326 description_visitor_gather_vla(description_visitor, &type_desc->u.side_gather, priv);
327 break;
328 default:
329 fprintf(stderr, "<UNKNOWN GATHER TYPE>");
330 abort();
331 }
332}
333
334static
335void visit_gather_elem(const struct side_description_visitor *description_visitor, const struct side_type *type_desc, void *priv)
336{
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);
342}
343
344static
345void description_visitor_gather_enum(const struct side_description_visitor *description_visitor, const struct side_type_gather *type_gather, void *priv)
346{
347 const struct side_type *elem_type = side_ptr_get(type_gather->u.side_enum.elem_type);
348
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);
354}
355
356static
357void side_visit_type(const struct side_description_visitor *description_visitor,
358 const struct side_type *type_desc, void *priv)
359{
360 enum side_type_label type = side_enum_get(type_desc->type);
361
362 switch (type) {
363 /* Stack-copy basic types */
364 case SIDE_TYPE_NULL:
365 if (description_visitor->null_type_func)
366 description_visitor->null_type_func(type_desc, priv);
367 break;
368 case SIDE_TYPE_BOOL:
369 if (description_visitor->bool_type_func)
370 description_visitor->bool_type_func(type_desc, priv);
371 break;
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 */
381 case SIDE_TYPE_S128:
382 if (description_visitor->integer_type_func)
383 description_visitor->integer_type_func(type_desc, priv);
384 break;
385 case SIDE_TYPE_BYTE:
386 if (description_visitor->byte_type_func)
387 description_visitor->byte_type_func(type_desc, priv);
388 break;
389 case SIDE_TYPE_POINTER:
390 if (description_visitor->pointer_type_func)
391 description_visitor->pointer_type_func(type_desc, priv);
392 break;
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);
399 break;
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);
405 break;
406 case SIDE_TYPE_ENUM:
407 description_visitor_enum(description_visitor, type_desc, priv);
408 break;
409 case SIDE_TYPE_ENUM_BITMAP:
410 description_visitor_enum_bitmap(description_visitor, type_desc, priv);
411 break;
412
413 /* Stack-copy compound types */
414 case SIDE_TYPE_STRUCT:
415 description_visitor_struct(description_visitor, type_desc, priv);
416 break;
417 case SIDE_TYPE_VARIANT:
418 description_visitor_variant(description_visitor, type_desc, priv);
419 break;
420 case SIDE_TYPE_ARRAY:
421 description_visitor_array(description_visitor, type_desc, priv);
422 break;
423 case SIDE_TYPE_VLA:
424 description_visitor_vla(description_visitor, type_desc, priv);
425 break;
426 case SIDE_TYPE_VLA_VISITOR:
427 description_visitor_vla_visitor(description_visitor, type_desc, priv);
428 break;
429
430 /* Gather basic types */
431 case SIDE_TYPE_GATHER_BOOL:
432 description_visitor_gather_bool(description_visitor, &type_desc->u.side_gather, priv);
433 break;
434 case SIDE_TYPE_GATHER_INTEGER:
435 description_visitor_gather_integer(description_visitor, &type_desc->u.side_gather, SIDE_TYPE_GATHER_INTEGER, priv);
436 break;
437 case SIDE_TYPE_GATHER_BYTE:
438 description_visitor_gather_byte(description_visitor, &type_desc->u.side_gather, priv);
439 break;
440 case SIDE_TYPE_GATHER_POINTER:
441 description_visitor_gather_integer(description_visitor, &type_desc->u.side_gather, SIDE_TYPE_GATHER_POINTER, priv);
442 break;
443 case SIDE_TYPE_GATHER_FLOAT:
444 description_visitor_gather_float(description_visitor, &type_desc->u.side_gather, priv);
445 break;
446 case SIDE_TYPE_GATHER_STRING:
447 description_visitor_gather_string(description_visitor, &type_desc->u.side_gather, priv);
448 break;
449
450 /* Gather compound type */
451 case SIDE_TYPE_GATHER_STRUCT:
452 description_visitor_gather_struct(description_visitor, &type_desc->u.side_gather, priv);
453 break;
454 case SIDE_TYPE_GATHER_ARRAY:
455 description_visitor_gather_array(description_visitor, &type_desc->u.side_gather, priv);
456 break;
457 case SIDE_TYPE_GATHER_VLA:
458 description_visitor_gather_vla(description_visitor, &type_desc->u.side_gather, priv);
459 break;
460
461 /* Gather enumeration types */
462 case SIDE_TYPE_GATHER_ENUM:
463 description_visitor_gather_enum(description_visitor, &type_desc->u.side_gather, priv);
464 break;
465
466 /* Dynamic type */
467 case SIDE_TYPE_DYNAMIC:
468 if (description_visitor->dynamic_type_func)
469 description_visitor->dynamic_type_func(type_desc, priv);
470 break;
471
472 default:
473 fprintf(stderr, "<UNKNOWN TYPE>\n");
474 abort();
475 }
476}
477
478void description_visitor_event(const struct side_description_visitor *description_visitor,
479 const struct side_event_description *desc, void *priv)
480{
481 uint32_t i, len = desc->nr_fields;
482
483 if (description_visitor->event_func)
484 description_visitor->event_func(SIDE_DESCRIPTION_VISITOR_BEFORE, desc, priv);
485 if (len) {
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);
492 }
493 if (description_visitor->event_func)
494 description_visitor->event_func(SIDE_DESCRIPTION_VISITOR_AFTER, desc, priv);
495}
This page took 0.046539 seconds and 4 git commands to generate.