Add user static array field support (with recursion)
This patch adds support for user static array fields.
The element field type of a user static array field type can be any of
the following:
* Bit array field type.
* String field type.
* Static array field type.
The generated serializing C code does not assume anything about the
memory layout of a user array: it iterates each item to serialize them
individually.
For example, consider the following TSDL field type:
class: static-array
length: 3
element-field-type:
class: unsigned-integer
size: 16
The tracing function's parameter's C type for the corresponding field is
`const uint16_t *`. Assuming the parameter's name is `a`, the
serialization function accesses `a[0]`, `a[1]`, and `a[2]`; it doesn't
copy large blocks of memory as is. This is because we don't know the
target architecture's alignment constraints and general memory layout.
For:
class: static-array
length: 3
element-field-type:
class: string
the parameter's C type is `const char * const *`.
Note that a pointed C type is always `const`, so the `barectf.h` user
might need to cast accordingly if her own C types miss such `const`
qualifiers. Here's another example:
class: static-array
length: 2
element-field-type:
class: static-array
length: 3
element-field-type:
class: unsigned-integer
size: 8
This becomes `const uint8_t * const *`.
As of this patch, a tracing function uses `uint32_t` as the loop index
type. I believe this will be enough for barectf's use cases. It could
(should) also be based on the static array field type's length.
Each loop is isolated within its own C scope. The loop index variable
names are `i`, then `j`, then `k`, then `k1`, then `k2`, and so on.
Notable changes
===============
`cgen.py`:
* Add a level property to operation objects.
This is the static array nesting level.
* _OpBuilder._build_for_ft(): handle user static array field types.
A user static array field type leads to an "align" operation
(possibly) and its element field type's operation, all within a
compound operation.
The name of the element field type's operation is the C array
subscript with the right index variable name, for example `[i]`.
The packet header's UUID field type still has its special case.
* Add _loop_var_name() function which returns the name of a loop
index variable name based on a level (0 is `i`, 1 is `j`, and so
on).
* Add general template filter `loop_var_name` which is
_loop_var_name().
* Add general template filter `op_src_var_name` which returns an
operation's source variable name.
This used to be the op_src() macro in `c/common.j2`, but with
array subscript names, it's too ugly for the Jinja 2 language.
* _CodeGen._ft_c_type(): handle static array field types (return a
`_PointerCType` object).
`config_parse_v3.py`:
Accept user static array field types.
Existing templates:
Remove op_src(); use the `op_src_var_name` filter instead.
`serialize-write-static-array-statements.j2`,
`size-write-static-array-statements.j2`:
New templates to serialize and compute the size of static array
fields.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
This page took 0.024209 seconds and 4 git commands to generate.