Jinja: Variable length array types incorrectly appear to be fixed length in some contexts

For the sake of brevity I will provide a couple of simple data types and a snippet of Jinja to add to the default C templates. Given the following data type declarations:


# InnerType.1.0

bool[<=32] some_bits
# Some bits.



# OuterType.1.0

stuff.InnerType.1.0 bits_here;
# Need some bits.


If you modify the c/templates/definitions.j2 to add the following macro:

{% macro _count_things(t) %}
{%- set count = namespace(value=0) -%}
{%- for f in t.fields_except_padding %}
  {%- if f.data_type is StructureType %}
    {%- set count.value = count.value + (_count_things(f.data_type) | trim | int) %}
  {%- elif f.data_type is ArrayType %}
    {%- if f.data_type is VariableLengthArrayType %}
      {#- add 2 for variable length arrays #}
      {%- set count.value = count.value + 2 %}
    {%- elif f.data_type is FixedLengthArrayType %}
      {%- set count.value = count.value + 3 %}
    {%- endif %}
  {%- else %}
    {%- set count.value = count.value + 1 %}
  {%- endif %}
{%- endfor %}
{{ count.value }}
{% endmacro %}

And call it like so:

#define {{ ref }}_THING_COUNT_ ({{ _count_things(t) | trim | int }})

What you’ll see is that for InnerType, you see stuff_InnerType_1_0_THING_COUNT_ (2), which is exactly what you’d expect. However, for OuterType, you will see stuff_OuterType_1_0_THING_COUNT_ (3), implying that bits_here.data_type has a field which is FixedLengthArrayType.

Unfortunately, I don’t have any more information to run with than this, but I’d be happy to investigate or provide other information if possible.

I think it has something to do with the way your macro invokes itself recursively when it encounters OuterType.bits_here, which is a StructureType. Nunavut does not misrepresent variable-length arrays as fixed-length ones, nor vice versa.

Could you elaborate? I’m not sure I understand how the recursive invocation differs from the top-level. I am not sure I understand how f.data_type (bits_here.data_type) is different from the top-level invocation of _count_things(InnerType).

I should note that I am not attempting to unduly accuse nunavut for this issue, it could definitely be a misunderstanding on my part. However, based on the behavior of things like _define_field, I don’t see why this macro doesn’t work.