Commit 7b5fe80e authored by Jakub Kicinski's avatar Jakub Kicinski

tools: ynl-gen: print prototypes for recursive stuff

We avoid printing forward declarations and prototypes for most
types by sorting things topologically. But if structs nest we
do need the forward declarations, there's no other way.
Reviewed-by: default avatarDonald Hunter <donald.hunter@gmail.com>
Link: https://lore.kernel.org/r/20231213231432.2944749-9-kuba@kernel.orgSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 461f25a2
...@@ -1521,6 +1521,10 @@ def print_dump_prototype(ri): ...@@ -1521,6 +1521,10 @@ def print_dump_prototype(ri):
print_prototype(ri, "request") print_prototype(ri, "request")
def put_typol_fwd(cw, struct):
cw.p(f'extern struct ynl_policy_nest {struct.render_name}_nest;')
def put_typol(cw, struct): def put_typol(cw, struct):
type_max = struct.attr_set.max_name type_max = struct.attr_set.max_name
cw.block_start(line=f'struct ynl_policy_attr {struct.render_name}_policy[{type_max} + 1] =') cw.block_start(line=f'struct ynl_policy_attr {struct.render_name}_policy[{type_max} + 1] =')
...@@ -1594,12 +1598,17 @@ def put_enum_to_str(family, cw, enum): ...@@ -1594,12 +1598,17 @@ def put_enum_to_str(family, cw, enum):
_put_enum_to_str_helper(cw, enum.render_name, map_name, 'value', enum=enum) _put_enum_to_str_helper(cw, enum.render_name, map_name, 'value', enum=enum)
def put_req_nested(ri, struct): def put_req_nested_prototype(ri, struct, suffix=';'):
func_args = ['struct nlmsghdr *nlh', func_args = ['struct nlmsghdr *nlh',
'unsigned int attr_type', 'unsigned int attr_type',
f'{struct.ptr_name}obj'] f'{struct.ptr_name}obj']
ri.cw.write_func_prot('int', f'{struct.render_name}_put', func_args) ri.cw.write_func_prot('int', f'{struct.render_name}_put', func_args,
suffix=suffix)
def put_req_nested(ri, struct):
put_req_nested_prototype(ri, struct, suffix='')
ri.cw.block_start() ri.cw.block_start()
ri.cw.write_func_lvar('struct nlattr *nest;') ri.cw.write_func_lvar('struct nlattr *nest;')
...@@ -1726,18 +1735,23 @@ def _multi_parse(ri, struct, init_lines, local_vars): ...@@ -1726,18 +1735,23 @@ def _multi_parse(ri, struct, init_lines, local_vars):
ri.cw.nl() ri.cw.nl()
def parse_rsp_nested(ri, struct): def parse_rsp_nested_prototype(ri, struct, suffix=';'):
func_args = ['struct ynl_parse_arg *yarg', func_args = ['struct ynl_parse_arg *yarg',
'const struct nlattr *nested'] 'const struct nlattr *nested']
for arg in struct.inherited: for arg in struct.inherited:
func_args.append('__u32 ' + arg) func_args.append('__u32 ' + arg)
ri.cw.write_func_prot('int', f'{struct.render_name}_parse', func_args,
suffix=suffix)
def parse_rsp_nested(ri, struct):
parse_rsp_nested_prototype(ri, struct, suffix='')
local_vars = ['const struct nlattr *attr;', local_vars = ['const struct nlattr *attr;',
f'{struct.ptr_name}dst = yarg->data;'] f'{struct.ptr_name}dst = yarg->data;']
init_lines = [] init_lines = []
ri.cw.write_func_prot('int', f'{struct.render_name}_parse', func_args)
_multi_parse(ri, struct, init_lines, local_vars) _multi_parse(ri, struct, init_lines, local_vars)
...@@ -2051,6 +2065,10 @@ def _free_type(ri, direction, struct): ...@@ -2051,6 +2065,10 @@ def _free_type(ri, direction, struct):
ri.cw.nl() ri.cw.nl()
def free_rsp_nested_prototype(ri):
print_free_prototype(ri, "")
def free_rsp_nested(ri, struct): def free_rsp_nested(ri, struct):
_free_type(ri, "", struct) _free_type(ri, "", struct)
...@@ -2818,7 +2836,14 @@ def main(): ...@@ -2818,7 +2836,14 @@ def main():
put_enum_to_str(parsed, cw, const) put_enum_to_str(parsed, cw, const)
cw.nl() cw.nl()
has_recursive_nests = False
cw.p('/* Policies */') cw.p('/* Policies */')
for struct in parsed.pure_nested_structs.values():
if struct.recursive:
put_typol_fwd(cw, struct)
has_recursive_nests = True
if has_recursive_nests:
cw.nl()
for name in parsed.pure_nested_structs: for name in parsed.pure_nested_structs:
struct = Struct(parsed, name) struct = Struct(parsed, name)
put_typol(cw, struct) put_typol(cw, struct)
...@@ -2827,6 +2852,15 @@ def main(): ...@@ -2827,6 +2852,15 @@ def main():
put_typol(cw, struct) put_typol(cw, struct)
cw.p('/* Common nested types */') cw.p('/* Common nested types */')
if has_recursive_nests:
for attr_set, struct in parsed.pure_nested_structs.items():
ri = RenderInfo(cw, parsed, args.mode, "", "", attr_set)
free_rsp_nested_prototype(ri)
if struct.request:
put_req_nested_prototype(ri, struct)
if struct.reply:
parse_rsp_nested_prototype(ri, struct)
cw.nl()
for attr_set, struct in parsed.pure_nested_structs.items(): for attr_set, struct in parsed.pure_nested_structs.items():
ri = RenderInfo(cw, parsed, args.mode, "", "", attr_set) ri = RenderInfo(cw, parsed, args.mode, "", "", attr_set)
......
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