diff options
author | Ole Troan <otroan@employees.org> | 2024-09-10 23:37:56 +0200 |
---|---|---|
committer | Andrew Yourtchenko <ayourtch@gmail.com> | 2024-09-12 12:56:56 +0000 |
commit | 9a3f387c3010e6beecb14bac595cad306cc8e661 (patch) | |
tree | b42cbbbf8aa3bd57441721c1309110011f6cfc36 /src/tools | |
parent | 3b5a013103f0eff44afbdc4937407a82931edd00 (diff) |
vppapigen: endian generation for vla for non u32
The endian function for VLAs assumed length field to be of type u32.
That failed for APIs using different integer width.
Type: fix
Change-Id: I6ecaabb4563c8bafeb100a4c6c1eee9a08e6cabf
Signed-off-by: Ole Troan <otroan@employees.org>
Diffstat (limited to 'src/tools')
-rwxr-xr-x | src/tools/vppapigen/vppapigen_c.py | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/src/tools/vppapigen/vppapigen_c.py b/src/tools/vppapigen/vppapigen_c.py index 2cd3c7989b3..3cd52df1ad0 100755 --- a/src/tools/vppapigen/vppapigen_c.py +++ b/src/tools/vppapigen/vppapigen_c.py @@ -1143,12 +1143,20 @@ ENDIAN_STRINGS = { } -def get_endian_string(o, fieldtype): +def get_endian_string(fieldtype): """Return proper endian string conversion function""" return ENDIAN_STRINGS[fieldtype] -def endianfun_array(o): +def get_lengthfield_type(fieldname, block): + """Return the type of the length field""" + for o in block: + if o.fieldname == fieldname: + return o.fieldtype + return None + + +def endianfun_array(o, block): """Generate endian functions for arrays""" forloop = """\ ASSERT((u32){length} <= (u32)VL_API_MAX_ARRAY_SIZE); @@ -1167,12 +1175,16 @@ def endianfun_array(o): if o.fieldtype == "u8" or o.fieldtype == "string" or o.fieldtype == "bool": output += " /* a->{n} = a->{n} (no-op) */\n".format(n=o.fieldname) else: - lfield = "a->" + o.lengthfield if o.lengthfield else o.length + # lfield = "a->" + o.lengthfield if o.lengthfield else o.length if o.lengthfield: - output += ( - f" u32 count = to_net ? clib_host_to_net_u32(a->{o.lengthfield}) : " - f"a->{o.lengthfield};\n" - ) + fieldtype = get_lengthfield_type(o.lengthfield, block) + if fieldtype == "u8": + output += f" u32 count = a->{o.lengthfield};\n" + else: + output += ( + f" u32 count = to_net ? {get_endian_string(fieldtype)}(a->{o.lengthfield}) : " + f"a->{o.lengthfield};\n" + ) lfield = "count" else: lfield = o.length @@ -1180,7 +1192,7 @@ def endianfun_array(o): if o.fieldtype in ENDIAN_STRINGS: output += forloop.format( length=lfield, - format=get_endian_string(o, o.fieldtype), + format=get_endian_string(o.fieldtype), name=o.fieldname, ) else: @@ -1193,11 +1205,11 @@ def endianfun_array(o): NO_ENDIAN_CONVERSION = {"client_index": None} -def endianfun_obj(o): +def endianfun_obj(o, block): """Generate endian conversion function for type""" output = "" if o.type == "Array": - return endianfun_array(o) + return endianfun_array(o, block) if o.type != "Field": output += ' s = format(s, "\\n{} {} {} (print not implemented");\n'.format( o.type, o.fieldtype, o.fieldname @@ -1208,7 +1220,7 @@ def endianfun_obj(o): return output if o.fieldtype in ENDIAN_STRINGS: output += " a->{name} = {format}(a->{name});\n".format( - name=o.fieldname, format=get_endian_string(o, o.fieldtype) + name=o.fieldname, format=get_endian_string(o.fieldtype) ) elif o.fieldtype.startswith("vl_api_"): output += " {type}_endian(&a->{name}, to_net);\n".format( @@ -1252,7 +1264,7 @@ static inline void vl_api_{name}_t_endian (vl_api_{name}_t *a, bool to_net) if t.__class__.__name__ == "Enum" or t.__class__.__name__ == "EnumFlag": output += signature.format(name=t.name) if t.enumtype in ENDIAN_STRINGS: - output += " *a = {}(*a);\n".format(get_endian_string(t, t.enumtype)) + output += " *a = {}(*a);\n".format(get_endian_string(t.enumtype)) else: output += " /* a->{name} = a->{name} (no-op) */\n".format( name=t.name @@ -1273,7 +1285,7 @@ static inline void vl_api_{name}_t_endian (vl_api_{name}_t *a, bool to_net) ) elif t.alias["type"] in FORMAT_STRINGS: output += " *a = {}(*a);\n".format( - get_endian_string(t, t.alias["type"]) + get_endian_string(t.alias["type"]) ) else: output += " /* Not Implemented yet {} */".format(t.name) @@ -1283,7 +1295,7 @@ static inline void vl_api_{name}_t_endian (vl_api_{name}_t *a, bool to_net) output += signature.format(name=t.name) for o in t.block: - output += endianfun_obj(o) + output += endianfun_obj(o, t.block) output += "}\n\n" output += "\n#endif" @@ -1349,7 +1361,7 @@ static inline uword vl_api_{name}_t_calc_size (vl_api_{name}_t *a) ) lf = m[0] if lf.fieldtype in ENDIAN_STRINGS: - output += f" + {get_endian_string(b, lf.fieldtype)}(a->{b.lengthfield}) * sizeof(a->{b.fieldname}[0])" + output += f" + {get_endian_string(lf.fieldtype)}(a->{b.lengthfield}) * sizeof(a->{b.fieldname}[0])" elif lf.fieldtype == "u8": output += ( f" + a->{b.lengthfield} * sizeof(a->{b.fieldname}[0])" |