Lines Matching full:self
44 def get_family_id(self): argument
49 def __init__(self, family, attr_set, attr, value): argument
52 self.attr = attr
53 self.attr_set = attr_set
54 self.type = attr['type']
55 self.checks = attr.get('checks', {})
57 self.request = False
58 self.reply = False
60 self.is_selector = False
63 self.len = attr['len']
73 self.nested_attrs = nested
74 if self.nested_attrs == family.name:
75 self.nested_render_name = c_lower(f"{family.ident_name}")
77 self.nested_render_name = c_lower(f"{family.ident_name}_{self.nested_attrs}")
79 if self.nested_attrs in self.family.consts:
80 self.nested_struct_type = 'struct ' + self.nested_render_name + '_'
82 self.nested_struct_type = 'struct ' + self.nested_render_name
84 self.c_name = c_lower(self.name)
85 if self.c_name in _C_KW:
86 self.c_name += '_'
87 if self.c_name[0].isdigit():
88 self.c_name = '_' + self.c_name
91 self.enum_name = None
92 delattr(self, "enum_name")
94 def _get_real_attr(self): argument
96 return self.family.attr_sets[self.attr_set.subset_of][self.name]
98 def set_request(self): argument
99 self.request = True
100 if self.attr_set.subset_of:
101 self._get_real_attr().set_request()
103 def set_reply(self): argument
104 self.reply = True
105 if self.attr_set.subset_of:
106 self._get_real_attr().set_reply()
108 def get_limit(self, limit, default=None): argument
109 value = self.checks.get(limit, default)
114 if value in self.family.consts:
115 return self.family.consts[value]["value"]
118 def get_limit_str(self, limit, default=None, suffix=''): argument
119 value = self.checks.get(limit, default)
124 if value in self.family.consts:
125 const = self.family.consts[value]
128 return c_upper(f"{self.family['name']}-{value}")
131 def resolve(self): argument
132 if 'parent-sub-message' in self.attr:
133 enum_name = self.attr['parent-sub-message'].enum_name
134 elif 'name-prefix' in self.attr:
135 enum_name = f"{self.attr['name-prefix']}{self.name}"
137 enum_name = f"{self.attr_set.name_prefix}{self.name}"
138 self.enum_name = c_upper(enum_name)
140 if self.attr_set.subset_of:
141 if self.checks != self._get_real_attr().checks:
144 def is_multi_val(self): argument
147 def is_scalar(self): argument
148 return self.type in {'u8', 'u16', 'u32', 'u64', 's32', 's64'}
150 def is_recursive(self): argument
153 def is_recursive_for_op(self, ri): argument
154 return self.is_recursive() and not ri.op
156 def presence_type(self): argument
159 def presence_member(self, space, type_filter): argument
160 if self.presence_type() != type_filter:
163 if self.presence_type() == 'present':
165 return f"{pfx}u32 {self.c_name}:1;"
167 if self.presence_type() in {'len', 'count'}:
169 return f"{pfx}u32 {self.c_name};"
171 def _complex_member_type(self, ri): argument
174 def free_needs_iter(self): argument
177 def _free_lines(self, ri, var, ref): argument
178 if self.is_multi_val() or self.presence_type() in {'count', 'len'}:
179 return [f'free({var}->{ref}{self.c_name});']
182 def free(self, ri, var, ref): argument
183 lines = self._free_lines(ri, var, ref)
187 def arg_member(self, ri): argument
188 member = self._complex_member_type(ri)
191 arg = [member + spc + '*' + self.c_name]
192 if self.presence_type() == 'count':
193 arg += ['unsigned int n_' + self.c_name]
195 raise Exception(f"Struct member not implemented for class type {self.type}")
197 def struct_member(self, ri): argument
198 member = self._complex_member_type(ri)
200 ptr = '*' if self.is_multi_val() else ''
201 if self.is_recursive_for_op(ri):
204 ri.cw.p(f"{member}{spc}{ptr}{self.c_name};")
206 members = self.arg_member(ri)
210 def _attr_policy(self, policy): argument
213 def attr_policy(self, cw): argument
214 policy = f'NLA_{c_upper(self.type)}'
215 if self.attr.get('byte-order') == 'big-endian':
216 if self.type in {'u16', 'u32'}:
217 policy = f'NLA_BE{self.type[1:]}'
219 spec = self._attr_policy(policy)
220 cw.p(f"\t[{self.enum_name}] = {spec},")
222 def _attr_typol(self): argument
223 raise Exception(f"Type policy not implemented for class type {self.type}")
225 def attr_typol(self, cw): argument
226 typol = self._attr_typol()
227 cw.p(f'[{self.enum_name}] = {"{"} .name = "{self.name}", {typol}{"}"},')
229 def _attr_put_line(self, ri, var, line): argument
230 presence = self.presence_type()
232 ri.cw.p(f"if ({var}->_{presence}.{self.c_name})")
235 def _attr_put_simple(self, ri, var, put_type): argument
236 line = f"ynl_attr_put_{put_type}(nlh, {self.enum_name}, {var}->{self.c_name})"
237 self._attr_put_line(ri, var, line)
239 def attr_put(self, ri, var): argument
240 raise Exception(f"Put not implemented for class type {self.type}")
242 def _attr_get(self, ri, var): argument
243 raise Exception(f"Attr get not implemented for class type {self.type}")
245 def attr_get(self, ri, var, first): argument
246 lines, init_lines, local_vars = self._attr_get(ri, var)
253 ri.cw.block_start(line=f"{kw} (type == {self.enum_name})")
259 if not self.is_multi_val():
262 if self.presence_type() == 'present':
263 ri.cw.p(f"{var}->_present.{self.c_name} = 1;")
275 def _setter_lines(self, ri, member, presence): argument
276 raise Exception(f"Setter not implemented for class type {self.type}")
278 def setter(self, ri, space, direction, deref=False, ref=None): argument
279 ref = (ref if ref else []) + [self.c_name]
284 if self.free_needs_iter():
292 # last layer is "self" and may be a complex type
293 if i == len(ref) - 1 and self.presence_type() != 'present':
294 presence = f"{var}->{'.'.join(ref[:i] + [''])}_{self.presence_type()}.{ref[i]}"
300 code += self._free_lines(ri, var, ref_path)
301 code += self._setter_lines(ri, member, presence)
310 … args=[f'{type_name(ri, direction, deref=deref)} *{var}'] + self.arg_member(ri))
314 def presence_type(self): argument
317 def arg_member(self, ri): argument
320 def _attr_get(self, ri, var): argument
323 def _attr_typol(self): argument
326 def attr_policy(self, cw): argument
329 def attr_put(self, ri, var): argument
332 def attr_get(self, ri, var, first): argument
335 def setter(self, ri, space, direction, deref=False, ref=None): argument
340 def presence_type(self): argument
343 def arg_member(self, ri): argument
346 def _attr_typol(self): argument
349 def attr_put(self, ri, var): argument
352 def attr_get(self, ri, var, first): argument
355 def attr_policy(self, cw): argument
358 def setter(self, ri, space, direction, deref=False, ref=None): argument
363 def __init__(self, family, attr_set, attr, value): argument
366 self.byte_order_comment = ''
368 self.byte_order_comment = f" /* {attr['byte-order']} */"
373 self._init_checks()
376 self.is_bitfield = None
377 delattr(self, "is_bitfield")
378 self.type_name = None
379 delattr(self, "type_name")
381 def resolve(self): argument
382 self.resolve_up(super())
384 if 'enum-as-flags' in self.attr and self.attr['enum-as-flags']:
385 self.is_bitfield = True
386 elif 'enum' in self.attr:
387 self.is_bitfield = self.family.consts[self.attr['enum']]['type'] == 'flags'
389 self.is_bitfield = False
391 if not self.is_bitfield and 'enum' in self.attr:
392 self.type_name = self.family.consts[self.attr['enum']].user_type
393 elif self.is_auto_scalar:
394 self.type_name = '__' + self.type[0] + '64'
396 self.type_name = '__' + self.type
398 def _init_checks(self): argument
399 if 'enum' in self.attr:
400 enum = self.family.consts[self.attr['enum']]
403 self.checks['sparse'] = True
405 if 'min' not in self.checks:
406 if low != 0 or self.type[0] == 's':
407 self.checks['min'] = low
408 if 'max' not in self.checks:
409 self.checks['max'] = high
411 if 'min' in self.checks and 'max' in self.checks:
412 if self.get_limit('min') > self.get_limit('max'):
413 …raise Exception(f'Invalid limit for "{self.name}" min: {self.get_limit("min")} max: {self.get_limi…
414 self.checks['range'] = True
416 low = min(self.get_limit('min', 0), self.get_limit('max', 0))
417 high = max(self.get_limit('min', 0), self.get_limit('max', 0))
418 if low < 0 and self.type[0] == 'u':
419 raise Exception(f'Invalid limit for "{self.name}" negative limit for unsigned type')
421 self.checks['full-range'] = True
423 def _attr_policy(self, policy): argument
424 if 'flags-mask' in self.checks or self.is_bitfield:
425 if self.is_bitfield:
426 enum = self.family.consts[self.attr['enum']]
429 flags = self.family.consts[self.checks['flags-mask']]
433 elif 'full-range' in self.checks:
434 return f"NLA_POLICY_FULL_RANGE({policy}, &{c_lower(self.enum_name)}_range)"
435 elif 'range' in self.checks:
436 … return f"NLA_POLICY_RANGE({policy}, {self.get_limit_str('min')}, {self.get_limit_str('max')})"
437 elif 'min' in self.checks:
438 return f"NLA_POLICY_MIN({policy}, {self.get_limit_str('min')})"
439 elif 'max' in self.checks:
440 return f"NLA_POLICY_MAX({policy}, {self.get_limit_str('max')})"
441 elif 'sparse' in self.checks:
442 return f"NLA_POLICY_VALIDATE_FN({policy}, &{c_lower(self.enum_name)}_validate)"
445 def _attr_typol(self): argument
446 return f'.type = YNL_PT_U{c_upper(self.type[1:])}, '
448 def arg_member(self, ri): argument
449 return [f'{self.type_name} {self.c_name}{self.byte_order_comment}']
451 def attr_put(self, ri, var): argument
452 self._attr_put_simple(ri, var, self.type)
454 def _attr_get(self, ri, var): argument
455 return f"{var}->{self.c_name} = ynl_attr_get_{self.type}(attr);", None, None
457 def _setter_lines(self, ri, member, presence): argument
458 return [f"{member} = {self.c_name};"]
462 def arg_member(self, ri): argument
465 def _attr_typol(self): argument
468 def attr_put(self, ri, var): argument
469 self._attr_put_line(ri, var, f"ynl_attr_put(nlh, {self.enum_name}, NULL, 0)")
471 def _attr_get(self, ri, var): argument
474 def _setter_lines(self, ri, member, presence): argument
479 def arg_member(self, ri): argument
480 return [f"const char *{self.c_name}"]
482 def presence_type(self): argument
485 def struct_member(self, ri): argument
486 ri.cw.p(f"char *{self.c_name};")
488 def _attr_typol(self): argument
490 if self.is_selector:
494 def _attr_policy(self, policy): argument
495 if 'exact-len' in self.checks:
496 mem = 'NLA_POLICY_EXACT_LEN(' + self.get_limit_str('exact-len') + ')'
499 if 'max-len' in self.checks:
500 mem += ', .len = ' + self.get_limit_str('max-len')
504 def attr_policy(self, cw): argument
505 if self.checks.get('unterminated-ok', False):
510 spec = self._attr_policy(policy)
511 cw.p(f"\t[{self.enum_name}] = {spec},")
513 def attr_put(self, ri, var): argument
514 self._attr_put_simple(ri, var, 'str')
516 def _attr_get(self, ri, var): argument
517 len_mem = var + '->_len.' + self.c_name
519 f"{var}->{self.c_name} = malloc(len + 1);",
520 f"memcpy({var}->{self.c_name}, ynl_attr_get_str(attr), len);",
521 f"{var}->{self.c_name}[len] = 0;"], \
525 def _setter_lines(self, ri, member, presence): argument
526 return [f"{presence} = strlen({self.c_name});",
528 f'memcpy({member}, {self.c_name}, {presence});',
533 def arg_member(self, ri): argument
534 return [f"const void *{self.c_name}", 'size_t len']
536 def presence_type(self): argument
539 def struct_member(self, ri): argument
540 ri.cw.p(f"void *{self.c_name};")
542 def _attr_typol(self): argument
545 def _attr_policy(self, policy): argument
546 if len(self.checks) == 0:
548 elif len(self.checks) == 1:
549 check_name = list(self.checks)[0]
555 if len(self.checks) == 0:
557 elif 'exact-len' in self.checks:
558 mem = 'NLA_POLICY_EXACT_LEN(' + self.get_limit_str('exact-len') + ')'
559 elif 'min-len' in self.checks:
560 mem = '{ .len = ' + self.get_limit_str('min-len') + ', }'
561 elif 'max-len' in self.checks:
562 mem = 'NLA_POLICY_MAX_LEN(' + self.get_limit_str('max-len') + ')'
566 def attr_put(self, ri, var): argument
567 self._attr_put_line(ri, var, f"ynl_attr_put(nlh, {self.enum_name}, " +
568 f"{var}->{self.c_name}, {var}->_len.{self.c_name})")
570 def _attr_get(self, ri, var): argument
571 len_mem = var + '->_len.' + self.c_name
573 f"{var}->{self.c_name} = malloc(len);",
574 f"memcpy({var}->{self.c_name}, ynl_attr_data(attr), len);"], \
578 def _setter_lines(self, ri, member, presence): argument
581 f'memcpy({member}, {self.c_name}, {presence});']
585 def struct_member(self, ri): argument
586 ri.cw.p(f'struct {c_lower(self.get("struct"))} *{self.c_name};')
588 def _attr_get(self, ri, var): argument
589 struct_sz = 'sizeof(struct ' + c_lower(self.get("struct")) + ')'
590 len_mem = var + '->_' + self.presence_type() + '.' + self.c_name
593 f"{var}->{self.c_name} = calloc(1, {struct_sz});",
595 f"{var}->{self.c_name} = malloc(len);",
596 f"memcpy({var}->{self.c_name}, ynl_attr_data(attr), len);"], \
602 def arg_member(self, ri): argument
603 return [f'__{self.get("sub-type")} *{self.c_name}', 'size_t count']
605 def presence_type(self): argument
608 def struct_member(self, ri): argument
609 ri.cw.p(f'__{self.get("sub-type")} *{self.c_name};')
611 def attr_put(self, ri, var): argument
612 presence = self.presence_type()
613 ri.cw.block_start(line=f"if ({var}->_{presence}.{self.c_name})")
614 ri.cw.p(f"i = {var}->_{presence}.{self.c_name} * sizeof(__{self.get('sub-type')});")
615 ri.cw.p(f"ynl_attr_put(nlh, {self.enum_name}, " +
616 f"{var}->{self.c_name}, i);")
619 def _attr_get(self, ri, var): argument
620 len_mem = var + '->_count.' + self.c_name
621 return [f"{len_mem} = len / sizeof(__{self.get('sub-type')});",
622 f"len = {len_mem} * sizeof(__{self.get('sub-type')});",
623 f"{var}->{self.c_name} = malloc(len);",
624 f"memcpy({var}->{self.c_name}, ynl_attr_data(attr), len);"], \
628 def _setter_lines(self, ri, member, presence): argument
630 f"count *= sizeof(__{self.get('sub-type')});",
632 f'memcpy({member}, {self.c_name}, count);']
636 def _complex_member_type(self, ri): argument
639 def _attr_typol(self): argument
642 def _attr_policy(self, policy): argument
643 if not 'enum' in self.attr:
645 enum = self.family.consts[self.attr['enum']]
649 def attr_put(self, ri, var): argument
650 …line = f"ynl_attr_put(nlh, {self.enum_name}, &{var}->{self.c_name}, sizeof(struct nla_bitfield32))"
651 self._attr_put_line(ri, var, line)
653 def _attr_get(self, ri, var): argument
654 …return f"memcpy(&{var}->{self.c_name}, ynl_attr_data(attr), sizeof(struct nla_bitfield32));", None…
656 def _setter_lines(self, ri, member, presence): argument
657 return [f"memcpy(&{member}, {self.c_name}, sizeof(struct nla_bitfield32));"]
661 def is_recursive(self): argument
662 return self.family.pure_nested_structs[self.nested_attrs].recursive
664 def _complex_member_type(self, ri): argument
665 return self.nested_struct_type
667 def _free_lines(self, ri, var, ref): argument
670 if self.is_recursive_for_op(ri):
672 lines += [f'if ({var}->{ref}{self.c_name})']
673 lines += [f'{self.nested_render_name}_free({at}{var}->{ref}{self.c_name});']
676 def _attr_typol(self): argument
677 return f'.type = YNL_PT_NEST, .nest = &{self.nested_render_name}_nest, '
679 def _attr_policy(self, policy): argument
680 return 'NLA_POLICY_NESTED(' + self.nested_render_name + '_nl_policy)'
682 def attr_put(self, ri, var): argument
683 at = '' if self.is_recursive_for_op(ri) else '&'
684 self._attr_put_line(ri, var, f"{self.nested_render_name}_put(nlh, " +
685 f"{self.enum_name}, {at}{var}->{self.c_name})")
687 def _attr_get(self, ri, var): argument
688 pns = self.family.pure_nested_structs[self.nested_attrs]
692 get_lines = [f"if ({self.nested_render_name}_parse({', '.join(args)}))",
694 init_lines = [f"parg.rsp_policy = &{self.nested_render_name}_nest;",
695 f"parg.data = &{var}->{self.c_name};"]
698 def setter(self, ri, space, direction, deref=False, ref=None): argument
699 ref = (ref if ref else []) + [self.c_name]
701 for _, attr in ri.family.pure_nested_structs[self.nested_attrs].member_list():
704 attr.setter(ri, self.nested_attrs, direction, deref=deref, ref=ref)
708 def __init__(self, family, attr_set, attr, value, base_type): argument
711 self.base_type = base_type
713 def is_multi_val(self): argument
716 def presence_type(self): argument
719 def _complex_member_type(self, ri): argument
720 if 'type' not in self.attr or self.attr['type'] == 'nest':
721 return self.nested_struct_type
722 elif self.attr['type'] == 'binary' and 'struct' in self.attr:
724 elif self.attr['type'] == 'string':
726 elif self.attr['type'] in scalars:
728 return scalar_pfx + self.attr['type']
730 raise Exception(f"Sub-type {self.attr['type']} not supported yet")
732 def arg_member(self, ri): argument
733 if self.type == 'binary' and 'struct' in self.attr:
734 return [f'struct {c_lower(self.attr["struct"])} *{self.c_name}',
735 f'unsigned int n_{self.c_name}']
738 def free_needs_iter(self): argument
739 return self.attr['type'] in {'nest', 'string'}
741 def _free_lines(self, ri, var, ref): argument
743 if self.attr['type'] in scalars:
744 lines += [f"free({var}->{ref}{self.c_name});"]
745 elif self.attr['type'] == 'binary':
746 lines += [f"free({var}->{ref}{self.c_name});"]
747 elif self.attr['type'] == 'string':
749 f"for (i = 0; i < {var}->{ref}_count.{self.c_name}; i++)",
750 f"free({var}->{ref}{self.c_name}[i]);",
751 f"free({var}->{ref}{self.c_name});",
753 elif 'type' not in self.attr or self.attr['type'] == 'nest':
755 f"for (i = 0; i < {var}->{ref}_count.{self.c_name}; i++)",
756 f'{self.nested_render_name}_free(&{var}->{ref}{self.c_name}[i]);',
757 f"free({var}->{ref}{self.c_name});",
760 raise Exception(f"Free of MultiAttr sub-type {self.attr['type']} not supported yet")
763 def _attr_policy(self, policy): argument
764 return self.base_type._attr_policy(policy)
766 def _attr_typol(self): argument
767 return self.base_type._attr_typol()
769 def _attr_get(self, ri, var): argument
770 return f'n_{self.c_name}++;', None, None
772 def attr_put(self, ri, var): argument
773 if self.attr['type'] in scalars:
774 put_type = self.type
775 ri.cw.p(f"for (i = 0; i < {var}->_count.{self.c_name}; i++)")
776 ri.cw.p(f"ynl_attr_put_{put_type}(nlh, {self.enum_name}, {var}->{self.c_name}[i]);")
777 elif self.attr['type'] == 'binary' and 'struct' in self.attr:
778 ri.cw.p(f"for (i = 0; i < {var}->_count.{self.c_name}; i++)")
779 …ri.cw.p(f"ynl_attr_put(nlh, {self.enum_name}, &{var}->{self.c_name}[i], sizeof(struct {c_lower(sel…
780 elif self.attr['type'] == 'string':
781 ri.cw.p(f"for (i = 0; i < {var}->_count.{self.c_name}; i++)")
782 ri.cw.p(f"ynl_attr_put_str(nlh, {self.enum_name}, {var}->{self.c_name}[i]->str);")
783 elif 'type' not in self.attr or self.attr['type'] == 'nest':
784 ri.cw.p(f"for (i = 0; i < {var}->_count.{self.c_name}; i++)")
785 self._attr_put_line(ri, var, f"{self.nested_render_name}_put(nlh, " +
786 f"{self.enum_name}, &{var}->{self.c_name}[i])")
788 raise Exception(f"Put of MultiAttr sub-type {self.attr['type']} not supported yet")
790 def _setter_lines(self, ri, member, presence): argument
791 return [f"{member} = {self.c_name};",
792 f"{presence} = n_{self.c_name};"]
796 def is_multi_val(self): argument
799 def presence_type(self): argument
802 def _complex_member_type(self, ri): argument
803 if 'sub-type' not in self.attr or self.attr['sub-type'] == 'nest':
804 return self.nested_struct_type
805 elif self.attr['sub-type'] in scalars:
807 return scalar_pfx + self.attr['sub-type']
808 elif self.attr['sub-type'] == 'binary' and 'exact-len' in self.checks:
811 raise Exception(f"Sub-type {self.attr['sub-type']} not supported yet")
813 def arg_member(self, ri): argument
814 if self.sub_type == 'binary' and 'exact-len' in self.checks:
815 return [f'unsigned char (*{self.c_name})[{self.checks["exact-len"]}]',
816 f'unsigned int n_{self.c_name}']
819 def _attr_typol(self): argument
820 if self.attr['sub-type'] in scalars:
821 return f'.type = YNL_PT_U{c_upper(self.sub_type[1:])}, '
822 elif self.attr['sub-type'] == 'binary' and 'exact-len' in self.checks:
823 return f'.type = YNL_PT_BINARY, .len = {self.checks["exact-len"]}, '
825 return f'.type = YNL_PT_NEST, .nest = &{self.nested_render_name}_nest, '
827 def _attr_get(self, ri, var): argument
829 get_lines = [f'attr_{self.c_name} = attr;',
833 f'\t{var}->_count.{self.c_name}++;',
837 def attr_put(self, ri, var): argument
838 ri.cw.p(f'array = ynl_attr_nest_start(nlh, {self.enum_name});')
839 if self.sub_type in scalars:
840 put_type = self.sub_type
841 ri.cw.block_start(line=f'for (i = 0; i < {var}->_count.{self.c_name}; i++)')
842 ri.cw.p(f"ynl_attr_put_{put_type}(nlh, i, {var}->{self.c_name}[i]);")
844 elif self.sub_type == 'binary' and 'exact-len' in self.checks:
845 ri.cw.p(f'for (i = 0; i < {var}->_count.{self.c_name}; i++)')
846 ri.cw.p(f"ynl_attr_put(nlh, i, {var}->{self.c_name}[i], {self.checks['exact-len']});")
847 elif self.sub_type == 'nest':
848 ri.cw.p(f'for (i = 0; i < {var}->_count.{self.c_name}; i++)')
849 ri.cw.p(f"{self.nested_render_name}_put(nlh, i, &{var}->{self.c_name}[i]);")
851 … raise Exception(f"Put for ArrayNest sub-type {self.attr['sub-type']} not supported, yet")
854 def _setter_lines(self, ri, member, presence): argument
855 return [f"{member} = {self.c_name};",
856 f"{presence} = n_{self.c_name};"]
860 def _complex_member_type(self, ri): argument
861 return self.nested_struct_type
863 def _attr_typol(self): argument
864 return f'.type = YNL_PT_NEST, .nest = &{self.nested_render_name}_nest, '
866 def _attr_get(self, ri, var): argument
871 init_lines = [f"parg.rsp_policy = &{self.nested_render_name}_nest;",
872 f"parg.data = &{var}->{self.c_name};"]
873 if 'type-value' in self.attr:
874 tv_names = [c_lower(x) for x in self.attr["type-value"]]
877 for level in self.attr["type-value"]:
885 get_lines += [f"{self.nested_render_name}_parse(&parg, {prev}{tv_args});"]
890 def __init__(self, family, attr_set, attr, value): argument
893 self.selector = Selector(attr, attr_set)
895 def _attr_typol(self): argument
896 typol = f'.type = YNL_PT_NEST, .nest = &{self.nested_render_name}_nest, '
901 if not self.selector.is_external():
902 typol += f'.selector_type = {self.attr_set[self["selector"]].value} '
905 def _attr_get(self, ri, var): argument
906 sel = c_lower(self['selector'])
907 if self.selector.is_external():
913 (self.name, self['selector']),
914 f"if ({self.nested_render_name}_parse(&parg, {sel_var}, attr))",
916 init_lines = [f"parg.rsp_policy = &{self.nested_render_name}_nest;",
917 f"parg.data = &{var}->{self.c_name};"]
922 def __init__(self, msg_attr, attr_set): argument
923 self.name = msg_attr["selector"]
925 if self.name in attr_set:
926 self.attr = attr_set[self.name]
927 self.attr.is_selector = True
928 self._external = False
931 self.attr = None
932 self._external = True
934 def set_attr(self, attr): argument
935 self.attr = attr
937 def is_external(self): argument
938 return self._external
942 def __init__(self, family, space_name, type_list=None, fixed_header=None, argument
944 self.family = family
945 self.space_name = space_name
946 self.attr_set = family.attr_sets[space_name]
948 self._inherited = inherited if inherited is not None else []
949 self.inherited = []
950 self.fixed_header = None
952 self.fixed_header = 'struct ' + c_lower(fixed_header)
953 self.submsg = submsg
955 self.nested = type_list is None
957 self.render_name = c_lower(family.ident_name)
959 self.render_name = c_lower(family.ident_name + '-' + space_name)
960 self.struct_name = 'struct ' + self.render_name
961 if self.nested and space_name in family.consts:
962 self.struct_name += '_'
963 self.ptr_name = self.struct_name + ' *'
965 self.child_nests = set()
967 self.request = False
968 self.reply = False
969 self.recursive = False
970 self.in_multi_val = False # used by a MultiAttr or and legacy arrays
972 self.attr_list = []
973 self.attrs = dict()
976 self.attr_list.append((t, self.attr_set[t]),)
978 for t in self.attr_set:
979 self.attr_list.append((t, self.attr_set[t]),)
982 self.attr_max_val = None
983 for name, attr in self.attr_list:
986 self.attr_max_val = attr
987 self.attrs[name] = attr
989 def __iter__(self): argument
990 yield from self.attrs
992 def __getitem__(self, key): argument
993 return self.attrs[key]
995 def member_list(self): argument
996 return self.attr_list
998 def set_inherited(self, new_inherited): argument
999 if self._inherited != new_inherited:
1001 self.inherited = [c_lower(x) for x in sorted(self._inherited)]
1003 def external_selectors(self): argument
1005 for name, attr in self.attr_list:
1010 def free_needs_iter(self): argument
1011 for _, attr in self.attr_list:
1018 def __init__(self, enum_set, yaml, prev, value_start): argument
1022 self.value_change = (self.value != prev.value + 1)
1024 self.value_change = (self.value != 0)
1025 self.value_change = self.value_change or self.enum_set['type'] == 'flags'
1028 self.c_name = None
1029 delattr(self, "c_name")
1031 def resolve(self): argument
1032 self.resolve_up(super())
1034 self.c_name = c_upper(self.enum_set.value_pfx + self.name)
1038 def __init__(self, family, yaml): argument
1039 self.render_name = c_lower(family.ident_name + '-' + yaml['name'])
1043 self.enum_name = 'enum ' + c_lower(yaml['enum-name'])
1044 self.user_type = self.enum_name
1046 self.enum_name = None
1048 self.enum_name = 'enum ' + self.render_name
1050 if self.enum_name:
1051 self.user_type = self.enum_name
1053 self.user_type = 'int'
1055 self.value_pfx = yaml.get('name-prefix', f"{family.ident_name}-{yaml['name']}-")
1056 self.header = yaml.get('header', None)
1057 self.enum_cnt_name = yaml.get('enum-cnt-name', None)
1061 def new_entry(self, entry, prev_entry, value_start): argument
1062 return EnumEntry(self, entry, prev_entry, value_start)
1064 def value_range(self): argument
1065 low = min([x.value for x in self.entries.values()])
1066 high = max([x.value for x in self.entries.values()])
1068 if high - low + 1 != len(self.entries):
1075 def __init__(self, family, yaml): argument
1078 if self.subset_of is None:
1081 elif self.name == family.name:
1084 pfx = f"{family.ident_name}-a-{self.name}-"
1085 self.name_prefix = c_upper(pfx)
1086 self.max_name = c_upper(self.yaml.get('attr-max-name', f"{self.name_prefix}max"))
1087 self.cnt_name = c_upper(self.yaml.get('attr-cnt-name', f"__{self.name_prefix}max"))
1089 self.name_prefix = family.attr_sets[self.subset_of].name_prefix
1090 self.max_name = family.attr_sets[self.subset_of].max_name
1091 self.cnt_name = family.attr_sets[self.subset_of].cnt_name
1094 self.c_name = None
1095 delattr(self, "c_name")
1097 def resolve(self): argument
1098 self.c_name = c_lower(self.name)
1099 if self.c_name in _C_KW:
1100 self.c_name += '_'
1101 if self.c_name == self.family.c_name:
1102 self.c_name = ''
1104 def new_attr(self, elem, value): argument
1106 t = TypeScalar(self.family, self, elem, value)
1108 t = TypeUnused(self.family, self, elem, value)
1110 t = TypePad(self.family, self, elem, value)
1112 t = TypeFlag(self.family, self, elem, value)
1114 t = TypeString(self.family, self, elem, value)
1117 t = TypeBinaryStruct(self.family, self, elem, value)
1119 t = TypeBinaryScalarArray(self.family, self, elem, value)
1121 t = TypeBinary(self.family, self, elem, value)
1123 t = TypeBitfield32(self.family, self, elem, value)
1125 t = TypeNest(self.family, self, elem, value)
1128 t = TypeArrayNest(self.family, self, elem, value)
1132 t = TypeNestTypeValue(self.family, self, elem, value)
1134 t = TypeSubMessage(self.family, self, elem, value)
1139 t = TypeMultiAttr(self.family, self, elem, value, t)
1145 def __init__(self, family, yaml, req_value, rsp_value): argument
1156 self.render_name = c_lower(family.ident_name + '_' + self.name)
1158 self.dual_policy = ('do' in yaml and 'request' in yaml['do']) and \
1161 self.has_ntf = False
1164 self.enum_name = None
1165 delattr(self, "enum_name")
1167 def resolve(self): argument
1168 self.resolve_up(super())
1170 if not self.is_async:
1171 self.enum_name = self.family.op_prefix + c_upper(self.name)
1173 self.enum_name = self.family.async_op_prefix + c_upper(self.name)
1175 def mark_has_ntf(self): argument
1176 self.has_ntf = True
1180 def __init__(self, family, yaml): argument
1183 self.render_name = c_lower(family.ident_name + '-' + yaml['name'])
1185 def resolve(self): argument
1186 self.resolve_up(super())
1190 def __init__(self, file_name, exclude_ops): argument
1192 self.c_name = None
1193 delattr(self, "c_name")
1194 self.op_prefix = None
1195 delattr(self, "op_prefix")
1196 self.async_op_prefix = None
1197 delattr(self, "async_op_prefix")
1198 self.mcgrps = None
1199 delattr(self, "mcgrps")
1200 self.consts = None
1201 delattr(self, "consts")
1202 self.hooks = None
1203 delattr(self, "hooks")
1207 self.fam_key = c_upper(self.yaml.get('c-family-name', self.yaml["name"] + '_FAMILY_NAME'))
1208 … self.ver_key = c_upper(self.yaml.get('c-version-name', self.yaml["name"] + '_FAMILY_VERSION'))
1210 if 'definitions' not in self.yaml:
1211 self.yaml['definitions'] = []
1213 if 'uapi-header' in self.yaml:
1214 self.uapi_header = self.yaml['uapi-header']
1216 self.uapi_header = f"linux/{self.ident_name}.h"
1217 if self.uapi_header.startswith("linux/") and self.uapi_header.endswith('.h'):
1218 self.uapi_header_name = self.uapi_header[6:-2]
1220 self.uapi_header_name = self.ident_name
1222 def resolve(self): argument
1223 self.resolve_up(super())
1225 self.c_name = c_lower(self.ident_name)
1226 if 'name-prefix' in self.yaml['operations']:
1227 self.op_prefix = c_upper(self.yaml['operations']['name-prefix'])
1229 self.op_prefix = c_upper(self.yaml['name'] + '-cmd-')
1230 if 'async-prefix' in self.yaml['operations']:
1231 self.async_op_prefix = c_upper(self.yaml['operations']['async-prefix'])
1233 self.async_op_prefix = self.op_prefix
1235 self.mcgrps = self.yaml.get('mcast-groups', {'list': []})
1237 self.hooks = dict()
1239 self.hooks[when] = dict()
1241 self.hooks[when][op_mode] = dict()
1242 self.hooks[when][op_mode]['set'] = set()
1243 self.hooks[when][op_mode]['list'] = []
1246 self.root_sets = dict()
1248 self.pure_nested_structs = dict()
1250 self._mark_notify()
1251 self._mock_up_events()
1253 self._load_root_sets()
1254 self._load_nested_sets()
1255 self._load_attr_use()
1256 self._load_selector_passing()
1257 self._load_hooks()
1259 self.kernel_policy = self.yaml.get('kernel-policy', 'split')
1260 if self.kernel_policy == 'global':
1261 self._load_global_policy()
1263 def new_enum(self, elem): argument
1264 return EnumSet(self, elem)
1266 def new_attr_set(self, elem): argument
1267 return AttrSet(self, elem)
1269 def new_operation(self, elem, req_value, rsp_value): argument
1270 return Operation(self, elem, req_value, rsp_value)
1272 def new_sub_message(self, elem): argument
1273 return SubMessage(self, elem)
1275 def is_classic(self): argument
1276 return self.proto == 'netlink-raw'
1278 def _mark_notify(self): argument
1279 for op in self.msgs.values():
1281 self.ops[op['notify']].mark_has_ntf()
1284 def _mock_up_events(self): argument
1285 for op in self.yaml['operations']['list']:
1293 def _load_root_sets(self): argument
1294 for op_name, op in self.msgs.items():
1308 if op['attribute-set'] not in self.root_sets:
1309 self.root_sets[op['attribute-set']] = {'request': req_attrs, 'reply': rsp_attrs}
1311 self.root_sets[op['attribute-set']]['request'].update(req_attrs)
1312 self.root_sets[op['attribute-set']]['reply'].update(rsp_attrs)
1314 def _sort_pure_types(self): argument
1316 pns_key_list = list(self.pure_nested_structs.keys())
1324 for _, spec in self.attr_sets[name].items():
1333 if self.pure_nested_structs[nested].recursive:
1337 struct = self.pure_nested_structs.pop(name)
1338 self.pure_nested_structs[name] = struct
1346 def _load_nested_set_nest(self, spec): argument
1349 if nested not in self.root_sets:
1350 if nested not in self.pure_nested_structs:
1351 self.pure_nested_structs[nested] = \
1352 Struct(self, nested, inherited=inherit,
1358 if nested in self.root_sets:
1363 self.pure_nested_structs[nested].set_inherited(inherit)
1367 def _load_nested_set_submsg(self, spec): argument
1370 submsg = self.sub_msgs[spec["sub-message"]]
1395 self.attr_sets[nested] = AttrSet(self, {
1397 "name-pfx": self.name + '-' + spec.name + '-',
1401 if nested not in self.pure_nested_structs:
1402 self.pure_nested_structs[nested] = Struct(self, nested, submsg=submsg)
1406 def _load_nested_sets(self): argument
1407 attr_set_queue = list(self.root_sets.keys())
1408 attr_set_seen = set(self.root_sets.keys())
1412 for attr, spec in self.attr_sets[a_set].items():
1414 nested = self._load_nested_set_nest(spec)
1416 nested = self._load_nested_set_submsg(spec)
1424 for root_set, rs_members in self.root_sets.items():
1425 for attr, spec in self.attr_sets[root_set].items():
1435 self.pure_nested_structs[nested].request = True
1437 self.pure_nested_structs[nested].reply = True
1440 child = self.pure_nested_structs.get(nested)
1443 self._sort_pure_types()
1446 for attr_set, struct in reversed(self.pure_nested_structs.items()):
1447 for _, spec in self.attr_sets[attr_set].items():
1459 child = self.pure_nested_structs.get(child_name)
1468 self._sort_pure_types()
1470 def _load_attr_use(self): argument
1471 for _, struct in self.pure_nested_structs.items():
1479 for root_set, rs_members in self.root_sets.items():
1480 for attr, spec in self.attr_sets[root_set].items():
1486 def _load_selector_passing(self): argument
1488 for k, v in reversed(self.pure_nested_structs.items()):
1490 for k, _ in self.root_sets.items():
1494 for _, spec in self.attr_sets[attr_set].items():
1502 child = self.pure_nested_structs.get(child_name)
1504 if selector.name in self.attr_sets[attr_set]:
1505 sel_attr = self.attr_sets[attr_set][selector.name]
1510 def _load_global_policy(self): argument
1513 for op_name, op in self.ops.items():
1530 self.global_policy = []
1531 self.global_policy_set = attr_set_name
1532 for attr in self.attr_sets[attr_set_name]:
1534 self.global_policy.append(attr)
1536 def _load_hooks(self): argument
1537 for op in self.ops.values():
1545 if name in self.hooks[when][op_mode]['set']:
1547 self.hooks[when][op_mode]['set'].add(name)
1548 self.hooks[when][op_mode]['list'].append(name)
1552 def __init__(self, cw, family, ku_space, op, op_mode, attr_set=None): argument
1553 self.family = family
1554 self.nl = cw.nlib
1555 self.ku_space = ku_space
1556 self.op_mode = op_mode
1557 self.op = op
1560 self.fixed_hdr_len = 'ys->family->hdr_len'
1564 self.fixed_hdr_len = f"sizeof(struct {c_lower(fixed_hdr)})"
1570 self.type_consistent = True
1571 self.type_oneside = False
1575 self.type_consistent = False
1577 self.type_consistent = False
1579 self.type_consistent = True
1580 self.type_oneside = True
1582 self.attr_set = attr_set
1583 if not self.attr_set:
1584 self.attr_set = op['attribute-set']
1586 self.type_name_conflict = False
1588 self.type_name = c_lower(op.name)
1590 self.type_name = c_lower(attr_set)
1592 self.type_name_conflict = True
1594 self.cw = cw
1596 self.struct = dict()
1604 self.struct[op_dir] = Struct(family, self.attr_set,
1608 self.struct['reply'] = Struct(family, self.attr_set,
1612 def type_empty(self, key): argument
1613 return len(self.struct[key].attr_list) == 0 and \
1614 self.struct['request'].fixed_header is None
1616 def needs_nlflags(self, direction): argument
1617 return self.op_mode == 'do' and direction == 'request' and self.family.is_classic()
1621 def __init__(self, nlib, out_file=None, overwrite=True): argument
1622 self.nlib = nlib
1623 self._overwrite = overwrite
1625 self._nl = False
1626 self._block_end = False
1627 self._silent_block = False
1628 self._ind = 0
1629 self._ifdef_block = None
1631 self._out = os.sys.stdout
1633 self._out = tempfile.NamedTemporaryFile('w+')
1634 self._out_file = out_file
1636 def __del__(self): argument
1637 self.close_out_file()
1639 def close_out_file(self): argument
1640 if self._out == os.sys.stdout:
1643 self._out.flush()
1644 if not self._overwrite and os.path.isfile(self._out_file):
1645 if filecmp.cmp(self._out.name, self._out_file, shallow=False):
1647 with open(self._out_file, 'w+') as out_file:
1648 self._out.seek(0)
1649 shutil.copyfileobj(self._out, out_file)
1650 self._out.close()
1651 self._out = os.sys.stdout
1657 def p(self, line, add_ind=0): argument
1658 if self._block_end:
1659 self._block_end = False
1663 self._out.write('\t' * self._ind + '}\n')
1665 if self._nl:
1666 self._out.write('\n')
1667 self._nl = False
1669 ind = self._ind
1672 if self._silent_block:
1674 self._silent_block = line.endswith(')') and CodeWriter._is_cond(line)
1675 self._silent_block |= line.strip() == 'else'
1680 self._out.write('\t' * ind + line + '\n')
1682 def nl(self): argument
1683 self._nl = True
1685 def block_start(self, line=''): argument
1688 self.p(line + '{')
1689 self._ind += 1
1691 def block_end(self, line=''): argument
1694 self._ind -= 1
1695 self._nl = False
1698 if self._block_end:
1699 self._out.write('\t' * (self._ind + 1) + '}\n')
1700 self._block_end = True
1702 self.p('}' + line)
1704 def write_doc_line(self, doc, indent=True): argument
1709 self.p(line)
1714 self.p(line)
1716 def write_func_prot(self, qual_ret, name, args=None, doc=None, suffix=''): argument
1721 self.p('/*')
1722 self.p(' * ' + doc)
1723 self.p(' */')
1731 self.p(oneline)
1736 self.p(v)
1750 self.p(v + ',')
1756 self.p(v + ')' + suffix)
1758 def write_func_lvar(self, local_vars): argument
1767 self.p(var)
1768 self.nl()
1770 def write_func(self, qual_ret, name, body, args=None, local_vars=None): argument
1771 self.write_func_prot(qual_ret=qual_ret, name=name, args=args)
1772 self.block_start()
1773 self.write_func_lvar(local_vars=local_vars)
1776 self.p(line)
1777 self.block_end()
1779 def writes_defines(self, defines): argument
1792 self.p(line)
1794 def write_struct_init(self, members): argument
1802 self.p(line)
1804 def ifdef_block(self, config): argument
1808 if self._ifdef_block == config_option:
1811 if self._ifdef_block:
1812 self.p('#endif /* ' + self._ifdef_block + ' */')
1814 self.p('#ifdef ' + config_option)
1815 self._ifdef_block = config_option