From 2cc9671a82e3ba8911f01b04fd8f8f2da3a238a7 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Tue, 6 Jun 2023 12:43:00 -0700 Subject: [PATCH] tools: ynl-gen: fill in support for MultiAttr scalars The handshake family needs support for MultiAttr scalars. Right now we only support code gen for MultiAttr nested types. Signed-off-by: Jakub Kicinski --- tools/net/ynl/ynl-gen-c.py | 47 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py index 1e64c5c..0a043ed 100755 --- a/tools/net/ynl/ynl-gen-c.py +++ b/tools/net/ynl/ynl-gen-c.py @@ -94,7 +94,10 @@ class Type(SpecAttr): def arg_member(self, ri): member = self._complex_member_type(ri) if member: - return [member + ' *' + self.c_name] + arg = [member + ' *' + self.c_name] + if self.presence_type() == 'count': + arg += ['unsigned int n_' + self.c_name] + return arg raise Exception(f"Struct member not implemented for class type {self.type}") def struct_member(self, ri): @@ -188,9 +191,12 @@ class Type(SpecAttr): code.append(presence + ' = 1;') code += self._setter_lines(ri, member, presence) - ri.cw.write_func('static inline void', - f"{op_prefix(ri, direction, deref=deref)}_set_{'_'.join(ref)}", - body=code, + func_name = f"{op_prefix(ri, direction, deref=deref)}_set_{'_'.join(ref)}" + free = bool([x for x in code if 'free(' in x]) + alloc = bool([x for x in code if 'alloc(' in x]) + if free and not alloc: + func_name = '__' + func_name + ri.cw.write_func('static inline void', func_name, body=code, args=[f'{type_name(ri, direction, deref=deref)} *{var}'] + self.arg_member(ri)) @@ -444,6 +450,13 @@ class TypeMultiAttr(Type): def presence_type(self): return 'count' + def _mnl_type(self): + t = self.type + # mnl does not have a helper for signed types + if t[0] == 's': + t = 'u' + t[1:] + return t + def _complex_member_type(self, ri): if 'type' not in self.attr or self.attr['type'] == 'nest': return f"struct {self.nested_render_name}" @@ -457,9 +470,14 @@ class TypeMultiAttr(Type): return 'type' not in self.attr or self.attr['type'] == 'nest' def free(self, ri, var, ref): - if 'type' not in self.attr or self.attr['type'] == 'nest': + if self.attr['type'] in scalars: + ri.cw.p(f"free({var}->{ref}{self.c_name});") + elif 'type' not in self.attr or self.attr['type'] == 'nest': ri.cw.p(f"for (i = 0; i < {var}->{ref}n_{self.c_name}; i++)") ri.cw.p(f'{self.nested_render_name}_free(&{var}->{ref}{self.c_name}[i]);') + ri.cw.p(f"free({var}->{ref}{self.c_name});") + else: + raise Exception(f"Free of MultiAttr sub-type {self.attr['type']} not supported yet") def _attr_typol(self): if 'type' not in self.attr or self.attr['type'] == 'nest': @@ -472,6 +490,25 @@ class TypeMultiAttr(Type): def _attr_get(self, ri, var): return f'{var}->n_{self.c_name}++;', None, None + def attr_put(self, ri, var): + if self.attr['type'] in scalars: + put_type = self._mnl_type() + ri.cw.p(f"for (unsigned int i = 0; i < {var}->n_{self.c_name}; i++)") + ri.cw.p(f"mnl_attr_put_{put_type}(nlh, {self.enum_name}, {var}->{self.c_name}[i]);") + elif 'type' not in self.attr or self.attr['type'] == 'nest': + ri.cw.p(f"for (unsigned int i = 0; i < {var}->n_{self.c_name}; i++)") + self._attr_put_line(ri, var, f"{self.nested_render_name}_put(nlh, " + + f"{self.enum_name}, &{var}->{self.c_name}[i])") + else: + raise Exception(f"Put of MultiAttr sub-type {self.attr['type']} not supported yet") + + def _setter_lines(self, ri, member, presence): + # For multi-attr we have a count, not presence, hack up the presence + presence = presence[:-(len('_present.') + len(self.c_name))] + "n_" + self.c_name + return [f"free({member});", + f"{member} = {self.c_name};", + f"{presence} = n_{self.c_name};"] + class TypeArrayNest(Type): def is_multi_val(self): -- 2.7.4