Don't modify the raw dicts (as loaded from YAML) to pretend
that the notify attributes also exist on the ops. This makes
the code easier to follow.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
attr_sets dict of attribute sets
msgs dict of all messages (index by name)
attr_sets dict of attribute sets
msgs dict of all messages (index by name)
- msgs_by_value dict of all messages (indexed by name)
ops dict of all valid requests / responses
ops dict of all valid requests / responses
+ ntfs dict of all async events
consts dict of all constants/enums
fixed_header string, optional name of family default fixed header struct
"""
consts dict of all constants/enums
fixed_header string, optional name of family default fixed header struct
"""
self.req_by_value = collections.OrderedDict()
self.rsp_by_value = collections.OrderedDict()
self.ops = collections.OrderedDict()
self.req_by_value = collections.OrderedDict()
self.rsp_by_value = collections.OrderedDict()
self.ops = collections.OrderedDict()
+ self.ntfs = collections.OrderedDict()
self.consts = collections.OrderedDict()
last_exception = None
self.consts = collections.OrderedDict()
last_exception = None
self.rsp_by_value[op.rsp_value] = op
if not op.is_async and 'attribute-set' in op:
self.ops[op.name] = op
self.rsp_by_value[op.rsp_value] = op
if not op.is_async and 'attribute-set' in op:
self.ops[op.name] = op
+ elif op.is_async:
+ self.ntfs[op.name] = op
self.dual_policy = ('do' in yaml and 'request' in yaml['do']) and \
('dump' in yaml and 'request' in yaml['dump'])
self.dual_policy = ('do' in yaml and 'request' in yaml['do']) and \
('dump' in yaml and 'request' in yaml['dump'])
# Added by resolve:
self.enum_name = None
delattr(self, "enum_name")
# Added by resolve:
self.enum_name = None
delattr(self, "enum_name")
else:
self.enum_name = self.family.async_op_prefix + c_upper(self.name)
else:
self.enum_name = self.family.async_op_prefix + c_upper(self.name)
- def add_notification(self, op):
- if 'notify' not in self.yaml:
- self.yaml['notify'] = dict()
- self.yaml['notify']['reply'] = self.yaml['do']['reply']
- self.yaml['notify']['cmds'] = []
- self.yaml['notify']['cmds'].append(op)
+ def mark_has_ntf(self):
+ self.has_ntf = True
class Family(SpecFamily):
class Family(SpecFamily):
self.root_sets = dict()
# dict space-name -> set('request', 'reply')
self.pure_nested_structs = dict()
self.root_sets = dict()
# dict space-name -> set('request', 'reply')
self.pure_nested_structs = dict()
- self.all_notify = dict()
self._load_root_sets()
self._load_nested_sets()
self._load_root_sets()
self._load_nested_sets()
- self._load_all_notify()
self._load_hooks()
self.kernel_policy = self.yaml.get('kernel-policy', 'split')
self._load_hooks()
self.kernel_policy = self.yaml.get('kernel-policy', 'split')
def new_operation(self, elem, req_value, rsp_value):
return Operation(self, elem, req_value, rsp_value)
def new_operation(self, elem, req_value, rsp_value):
return Operation(self, elem, req_value, rsp_value)
+ def _mark_notify(self):
+ for op in self.msgs.values():
+ if 'notify' in op:
+ self.ops[op['notify']].mark_has_ntf()
+
# Fake a 'do' equivalent of all events, so that we can render their response parsing
def _mock_up_events(self):
for op in self.yaml['operations']['list']:
# Fake a 'do' equivalent of all events, so that we can render their response parsing
def _mock_up_events(self):
for op in self.yaml['operations']['list']:
- def _dictify(self):
- ntf = []
- for msg in self.msgs.values():
- if 'notify' in msg:
- ntf.append(msg)
- for n in ntf:
- self.ops[n['notify']].add_notification(n)
-
def _load_root_sets(self):
for op_name, op in self.ops.items():
if 'attribute-set' not in op:
def _load_root_sets(self):
for op_name, op in self.ops.items():
if 'attribute-set' not in op:
child.request |= struct.request
child.reply |= struct.reply
child.request |= struct.request
child.reply |= struct.reply
- def _load_all_notify(self):
- for op_name, op in self.ops.items():
- if not op:
- continue
-
- if 'notify' in op:
- self.all_notify[op_name] = op['notify']['cmds']
-
def _load_global_policy(self):
global_set = set()
attr_set_name = None
def _load_global_policy(self):
global_set = set()
attr_set_name = None
self.hooks[when][op_mode]['set'].add(name)
self.hooks[when][op_mode]['list'].append(name)
self.hooks[when][op_mode]['set'].add(name)
self.hooks[when][op_mode]['list'].append(name)
- def has_notifications(self):
- for op in self.ops.values():
- if 'notify' in op or 'event' in op:
- return True
- return False
-
class RenderInfo:
def __init__(self, cw, family, ku_space, op, op_name, op_mode, attr_set=None):
self.family = family
self.nl = cw.nlib
self.ku_space = ku_space
class RenderInfo:
def __init__(self, cw, family, ku_space, op, op_name, op_mode, attr_set=None):
self.family = family
self.nl = cw.nlib
self.ku_space = ku_space
self.op = op
self.op_name = op_name
self.op = op
self.op_name = op_name
# 'do' and 'dump' response parsing is identical
self.type_consistent = True
# 'do' and 'dump' response parsing is identical
self.type_consistent = True
self.cw = cw
self.struct = dict()
self.cw = cw
self.struct = dict()
+ if op_mode == 'notify':
+ op_mode = 'do'
for op_dir in ['request', 'reply']:
if op and op_dir in op[op_mode]:
self.struct[op_dir] = Struct(family, self.attr_set,
for op_dir in ['request', 'reply']:
if op and op_dir in op[op_mode]:
self.struct[op_dir] = Struct(family, self.attr_set,
cw.p(f'extern {symbol};')
return
cw.p(f'extern {symbol};')
return
- ntf = family.has_notifications()
- if ntf:
cw.block_start(line=f"static const struct ynl_ntf_info {family['name']}_ntf_info[] = ")
cw.block_start(line=f"static const struct ynl_ntf_info {family['name']}_ntf_info[] = ")
- for ntf_op in sorted(family.all_notify.keys()):
- op = family.ops[ntf_op]
- ri = RenderInfo(cw, family, "user", op, ntf_op, "notify")
- for ntf in op['notify']['cmds']:
- _render_user_ntf_entry(ri, ntf)
+ for ntf_op_name, ntf_op in family.ntfs.items():
+ if 'notify' not in ntf_op:
+ continue
+ op = family.ops[ntf_op['notify']]
+ ri = RenderInfo(cw, family, "user", op, op.name, "notify")
+ _render_user_ntf_entry(ri, ntf_op)
for op_name, op in family.ops.items():
if 'event' not in op:
continue
for op_name, op in family.ops.items():
if 'event' not in op:
continue
cw.block_start(f'{symbol} = ')
cw.p(f'.name\t\t= "{family.name}",')
cw.block_start(f'{symbol} = ')
cw.p(f'.name\t\t= "{family.name}",')
cw.p(f".ntf_info\t= {family['name']}_ntf_info,")
cw.p(f".ntf_info_size\t= MNL_ARRAY_SIZE({family['name']}_ntf_info),")
cw.block_end(line=';')
cw.p(f".ntf_info\t= {family['name']}_ntf_info,")
cw.p(f".ntf_info_size\t= MNL_ARRAY_SIZE({family['name']}_ntf_info),")
cw.block_end(line=';')
print_dump_prototype(ri)
cw.nl()
print_dump_prototype(ri)
cw.nl()
cw.p(f"/* {op.enum_name} - notify */")
ri = RenderInfo(cw, parsed, args.mode, op, op_name, 'notify')
if not ri.type_consistent:
cw.p(f"/* {op.enum_name} - notify */")
ri = RenderInfo(cw, parsed, args.mode, op, op_name, 'notify')
if not ri.type_consistent:
cw.p(f"/* {op.enum_name} - notify */")
ri = RenderInfo(cw, parsed, args.mode, op, op_name, 'notify')
if not ri.type_consistent:
cw.p(f"/* {op.enum_name} - notify */")
ri = RenderInfo(cw, parsed, args.mode, op, op_name, 'notify')
if not ri.type_consistent: