aboutsummaryrefslogtreecommitdiffstats
path: root/src/tools/vppapigen/vppapigen_c.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/vppapigen/vppapigen_c.py')
-rwxr-xr-xsrc/tools/vppapigen/vppapigen_c.py124
1 files changed, 55 insertions, 69 deletions
diff --git a/src/tools/vppapigen/vppapigen_c.py b/src/tools/vppapigen/vppapigen_c.py
index fb7de0a023f..3cd52df1ad0 100755
--- a/src/tools/vppapigen/vppapigen_c.py
+++ b/src/tools/vppapigen/vppapigen_c.py
@@ -171,14 +171,10 @@ class ToJSON:
write(" {\n")
# What is length field doing here?
write(
- ' u8 *s = format(0, "0x%U", format_hex_bytes, '
+ ' char *s = format_c_string(0, "0x%U", format_hex_bytes_no_wrap, '
"&a->{n}, {lfield});\n".format(n=o.fieldname, lfield=lfield)
)
- write(
- ' cJSON_AddStringToObject(o, "{n}", (char *)s);\n'.format(
- n=o.fieldname
- )
- )
+ write(' cJSON_AddStringToObject(o, "{n}", s);\n'.format(n=o.fieldname))
write(" vec_free(s);\n")
write(" }\n")
return
@@ -275,8 +271,12 @@ class ToJSON:
"(vl_api_{name}_t *a) {{\n".format(name=o.name)
)
- write(' u8 *s = format(0, "%U", format_vl_api_{}_t, a);\n'.format(o.name))
- write(" cJSON *o = cJSON_CreateString((char *)s);\n")
+ write(
+ ' char *s = format_c_string(0, "%U", format_vl_api_{}_t, a);\n'.format(
+ o.name
+ )
+ )
+ write(" cJSON *o = cJSON_CreateString(s);\n")
write(" vec_free(s);\n")
write(" return o;\n")
write("}\n")
@@ -365,7 +365,7 @@ class FromJSON:
write(" char *p = cJSON_GetStringValue(item);\n")
write(" size_t plen = strlen(p);\n")
write(
- " {msgvar} = cJSON_realloc({msgvar}, {msgsize} + plen, {msgsize});\n".format(
+ " {msgvar} = cJSON_realloc({msgvar}, {msgsize} + plen);\n".format(
msgvar=msgvar, msgsize=msgsize
)
)
@@ -434,7 +434,7 @@ class FromJSON:
cJSON *array = cJSON_GetObjectItem(o, "{n}");
int size = cJSON_GetArraySize(array);
{lfield} = size;
- {realloc} = cJSON_realloc({realloc}, {msgsize} + sizeof({t}) * size, {msgsize});
+ {realloc} = cJSON_realloc({realloc}, {msgsize} + sizeof({t}) * size);
{t} *d = (void *){realloc} + {msgsize};
{msgsize} += sizeof({t}) * size;
for (i = 0; i < size; i++) {{
@@ -461,12 +461,12 @@ class FromJSON:
write(
" {realloc} = cJSON_realloc({realloc}, {msgsize} + "
- "vec_len(s), {msgsize});\n".format(
+ "vec_len(s));\n".format(
msgvar=msgvar, msgsize=msgsize, realloc=realloc
)
)
write(
- " memcpy((void *){realloc} + {msgsize}, s, "
+ " clib_memcpy((void *){realloc} + {msgsize}, s, "
"vec_len(s));\n".format(realloc=realloc, msgsize=msgsize)
)
write(" {msgsize} += vec_len(s);\n".format(msgsize=msgsize))
@@ -1143,20 +1143,22 @@ ENDIAN_STRINGS = {
}
-def get_endian_string(o, type):
+def get_endian_string(fieldtype):
"""Return proper endian string conversion function"""
- try:
- if o.to_network:
- return ENDIAN_STRINGS[type].replace("net_to_host", "host_to_net")
- except:
- pass
- return ENDIAN_STRINGS[type]
+ return ENDIAN_STRINGS[fieldtype]
+
+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):
+
+def endianfun_array(o, block):
"""Generate endian functions for arrays"""
forloop = """\
- {comment}
ASSERT((u32){length} <= (u32)VL_API_MAX_ARRAY_SIZE);
for (i = 0; i < {length}; i++) {{
a->{name}[i] = {format}(a->{name}[i]);
@@ -1165,33 +1167,32 @@ def endianfun_array(o):
forloop_format = """\
for (i = 0; i < {length}; i++) {{
- {type}_endian(&a->{name}[i]);
+ {type}_endian(&a->{name}[i], to_net);
}}
"""
- to_network_comment = ""
- try:
- if o.to_network:
- to_network_comment = """/*
- * Array fields processed first to handle variable length arrays and size
- * field endian conversion in the proper order for to-network messages.
- * Message fields have been sorted by type in the code generator, thus fields
- * in this generated code may be converted in a different order than specified
- * in the *.api file.
- */"""
- except:
- pass
-
output = ""
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:
+ 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
+
if o.fieldtype in ENDIAN_STRINGS:
output += forloop.format(
- comment=to_network_comment,
length=lfield,
- format=get_endian_string(o, o.fieldtype),
+ format=get_endian_string(o.fieldtype),
name=o.fieldname,
)
else:
@@ -1204,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
@@ -1219,10 +1220,10 @@ 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});\n".format(
+ output += " {type}_endian(&a->{name}, to_net);\n".format(
type=o.fieldtype, name=o.fieldname
)
else:
@@ -1254,23 +1255,16 @@ def endianfun(objs, modulename):
output = output.format(module=modulename)
signature = """\
-static inline void vl_api_{name}_t_endian (vl_api_{name}_t *a)
+static inline void vl_api_{name}_t_endian (vl_api_{name}_t *a, bool to_net)
{{
int i __attribute__((unused));
"""
for t in objs:
- # Outbound (to network) messages are identified by message nomenclature
- # i.e. message names ending with these suffixes are 'to network'
- if t.name.endswith("_reply") or t.name.endswith("_details"):
- t.to_network = True
- else:
- t.to_network = False
-
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
@@ -1291,7 +1285,7 @@ static inline void vl_api_{name}_t_endian (vl_api_{name}_t *a)
)
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)
@@ -1300,16 +1294,8 @@ static inline void vl_api_{name}_t_endian (vl_api_{name}_t *a)
output += signature.format(name=t.name)
- # For outbound (to network) messages:
- # some arrays have dynamic length -- iterate over
- # them before changing endianness for the length field
- # by making the Array types show up first
- if t.to_network:
- t.block.sort(key=lambda x: x.type)
-
for o in t.block:
- o.to_network = t.to_network
- output += endianfun_obj(o)
+ output += endianfun_obj(o, t.block)
output += "}\n\n"
output += "\n#endif"
@@ -1375,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])"
@@ -1852,7 +1838,7 @@ api_{n} (cJSON *o)
}}
mp->_vl_msg_id = vac_get_msg_index(VL_API_{N}_CRC);
- vl_api_{n}_t_endian(mp);
+ vl_api_{n}_t_endian(mp, 1);
vac_write((char *)mp, len);
cJSON_free(mp);
@@ -1867,7 +1853,7 @@ api_{n} (cJSON *o)
return 0;
}}
vl_api_{r}_t *rmp = (vl_api_{r}_t *)p;
- vl_api_{r}_t_endian(rmp);
+ vl_api_{r}_t_endian(rmp, 0);
return vl_api_{r}_t_tojson(rmp);
}}
@@ -1885,7 +1871,7 @@ api_{n} (cJSON *o)
return 0;
}}
mp->_vl_msg_id = msg_id;
- vl_api_{n}_t_endian(mp);
+ vl_api_{n}_t_endian(mp, 1);
vac_write((char *)mp, len);
cJSON_free(mp);
@@ -1919,7 +1905,7 @@ api_{n} (cJSON *o)
return 0;
}}
vl_api_{r}_t *rmp = (vl_api_{r}_t *)p;
- vl_api_{r}_t_endian(rmp);
+ vl_api_{r}_t_endian(rmp, 0);
cJSON_AddItemToArray(reply, vl_api_{r}_t_tojson(rmp));
}}
}}
@@ -1941,7 +1927,7 @@ api_{n} (cJSON *o)
}}
mp->_vl_msg_id = msg_id;
- vl_api_{n}_t_endian(mp);
+ vl_api_{n}_t_endian(mp, 1);
vac_write((char *)mp, len);
cJSON_free(mp);
@@ -1962,14 +1948,14 @@ api_{n} (cJSON *o)
u16 msg_id = ntohs(*((u16 *)p));
if (msg_id == reply_msg_id) {{
vl_api_{r}_t *rmp = (vl_api_{r}_t *)p;
- vl_api_{r}_t_endian(rmp);
+ vl_api_{r}_t_endian(rmp, 0);
cJSON_AddItemToArray(reply, vl_api_{r}_t_tojson(rmp));
break;
}}
if (msg_id == details_msg_id) {{
vl_api_{d}_t *rmp = (vl_api_{d}_t *)p;
- vl_api_{d}_t_endian(rmp);
+ vl_api_{d}_t_endian(rmp, 0);
cJSON_AddItemToArray(reply, vl_api_{d}_t_tojson(rmp));
}}
}}