Commit 461f25a2 authored by Jakub Kicinski's avatar Jakub Kicinski

tools: ynl-gen: store recursive nests by a pointer

To avoid infinite nesting store recursive structs by pointer.
If recursive struct is placed in the op directly - the first
instance can be stored by value. That makes the code much
less of a pain for majority of practical uses.
Reviewed-by: default avatarDonald Hunter <donald.hunter@gmail.com>
Link: https://lore.kernel.org/r/20231213231432.2944749-8-kuba@kernel.orgSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent aa75783b
...@@ -108,6 +108,9 @@ class Type(SpecAttr): ...@@ -108,6 +108,9 @@ class Type(SpecAttr):
def is_recursive(self): def is_recursive(self):
return False return False
def is_recursive_for_op(self, ri):
return self.is_recursive() and not ri.op
def presence_type(self): def presence_type(self):
return 'bit' return 'bit'
...@@ -148,6 +151,8 @@ class Type(SpecAttr): ...@@ -148,6 +151,8 @@ class Type(SpecAttr):
member = self._complex_member_type(ri) member = self._complex_member_type(ri)
if member: if member:
ptr = '*' if self.is_multi_val() else '' ptr = '*' if self.is_multi_val() else ''
if self.is_recursive_for_op(ri):
ptr = '*'
ri.cw.p(f"{member} {ptr}{self.c_name};") ri.cw.p(f"{member} {ptr}{self.c_name};")
return return
members = self.arg_member(ri) members = self.arg_member(ri)
...@@ -539,7 +544,11 @@ class TypeNest(Type): ...@@ -539,7 +544,11 @@ class TypeNest(Type):
return self.nested_struct_type return self.nested_struct_type
def free(self, ri, var, ref): def free(self, ri, var, ref):
ri.cw.p(f'{self.nested_render_name}_free(&{var}->{ref}{self.c_name});') at = '&'
if self.is_recursive_for_op(ri):
at = ''
ri.cw.p(f'if ({var}->{ref}{self.c_name})')
ri.cw.p(f'{self.nested_render_name}_free({at}{var}->{ref}{self.c_name});')
def _attr_typol(self): def _attr_typol(self):
return f'.type = YNL_PT_NEST, .nest = &{self.nested_render_name}_nest, ' return f'.type = YNL_PT_NEST, .nest = &{self.nested_render_name}_nest, '
...@@ -548,8 +557,9 @@ class TypeNest(Type): ...@@ -548,8 +557,9 @@ class TypeNest(Type):
return 'NLA_POLICY_NESTED(' + self.nested_render_name + '_nl_policy)' return 'NLA_POLICY_NESTED(' + self.nested_render_name + '_nl_policy)'
def attr_put(self, ri, var): def attr_put(self, ri, var):
at = '' if self.is_recursive_for_op(ri) else '&'
self._attr_put_line(ri, var, f"{self.nested_render_name}_put(nlh, " + self._attr_put_line(ri, var, f"{self.nested_render_name}_put(nlh, " +
f"{self.enum_name}, &{var}->{self.c_name})") f"{self.enum_name}, {at}{var}->{self.c_name})")
def _attr_get(self, ri, var): def _attr_get(self, ri, var):
get_lines = [f"if ({self.nested_render_name}_parse(&parg, attr))", get_lines = [f"if ({self.nested_render_name}_parse(&parg, attr))",
...@@ -562,6 +572,8 @@ class TypeNest(Type): ...@@ -562,6 +572,8 @@ class TypeNest(Type):
ref = (ref if ref else []) + [self.c_name] ref = (ref if ref else []) + [self.c_name]
for _, attr in ri.family.pure_nested_structs[self.nested_attrs].member_list(): for _, attr in ri.family.pure_nested_structs[self.nested_attrs].member_list():
if attr.is_recursive():
continue
attr.setter(ri, self.nested_attrs, direction, deref=deref, ref=ref) attr.setter(ri, self.nested_attrs, direction, deref=deref, ref=ref)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment