@@ -162,9 +162,15 @@ def _complex_member_type(self, ri):
162162 def free_needs_iter (self ):
163163 return False
164164
165- def free (self , ri , var , ref ):
165+ def _free_lines (self , ri , var , ref ):
166166 if self .is_multi_val () or self .presence_type () == 'len' :
167- ri .cw .p (f'free({ var } ->{ ref } { self .c_name } );' )
167+ return [f'free({ var } ->{ ref } { self .c_name } );' ]
168+ return []
169+
170+ def free (self , ri , var , ref ):
171+ lines = self ._free_lines (ri , var , ref )
172+ for line in lines :
173+ ri .cw .p (line )
168174
169175 def arg_member (self , ri ):
170176 member = self ._complex_member_type (ri )
@@ -263,6 +269,10 @@ def setter(self, ri, space, direction, deref=False, ref=None):
263269 var = "req"
264270 member = f"{ var } ->{ '.' .join (ref )} "
265271
272+ local_vars = []
273+ if self .free_needs_iter ():
274+ local_vars += ['unsigned int i;' ]
275+
266276 code = []
267277 presence = ''
268278 for i in range (0 , len (ref )):
@@ -272,14 +282,19 @@ def setter(self, ri, space, direction, deref=False, ref=None):
272282 if i == len (ref ) - 1 and self .presence_type () != 'bit' :
273283 continue
274284 code .append (presence + ' = 1;' )
285+ ref_path = '.' .join (ref [:- 1 ])
286+ if ref_path :
287+ ref_path += '.'
288+ code += self ._free_lines (ri , var , ref_path )
275289 code += self ._setter_lines (ri , member , presence )
276290
277291 func_name = f"{ op_prefix (ri , direction , deref = deref )} _set_{ '_' .join (ref )} "
278292 free = bool ([x for x in code if 'free(' in x ])
279293 alloc = bool ([x for x in code if 'alloc(' in x ])
280294 if free and not alloc :
281295 func_name = '__' + func_name
282- ri .cw .write_func ('static inline void' , func_name , body = code ,
296+ ri .cw .write_func ('static inline void' , func_name , local_vars = local_vars ,
297+ body = code ,
283298 args = [f'{ type_name (ri , direction , deref = deref )} *{ var } ' ] + self .arg_member (ri ))
284299
285300
@@ -482,8 +497,7 @@ def _attr_get(self, ri, var):
482497 ['unsigned int len;' ]
483498
484499 def _setter_lines (self , ri , member , presence ):
485- return [f"free({ member } );" ,
486- f"{ presence } _len = strlen({ self .c_name } );" ,
500+ return [f"{ presence } _len = strlen({ self .c_name } );" ,
487501 f"{ member } = malloc({ presence } _len + 1);" ,
488502 f'memcpy({ member } , { self .c_name } , { presence } _len);' ,
489503 f'{ member } [{ presence } _len] = 0;' ]
@@ -536,8 +550,7 @@ def _attr_get(self, ri, var):
536550 ['unsigned int len;' ]
537551
538552 def _setter_lines (self , ri , member , presence ):
539- return [f"free({ member } );" ,
540- f"{ presence } _len = len;" ,
553+ return [f"{ presence } _len = len;" ,
541554 f"{ member } = malloc({ presence } _len);" ,
542555 f'memcpy({ member } , { self .c_name } , { presence } _len);' ]
543556
@@ -574,12 +587,14 @@ def is_recursive(self):
574587 def _complex_member_type (self , ri ):
575588 return self .nested_struct_type
576589
577- def free (self , ri , var , ref ):
590+ def _free_lines (self , ri , var , ref ):
591+ lines = []
578592 at = '&'
579593 if self .is_recursive_for_op (ri ):
580594 at = ''
581- ri .cw .p (f'if ({ var } ->{ ref } { self .c_name } )' )
582- ri .cw .p (f'{ self .nested_render_name } _free({ at } { var } ->{ ref } { self .c_name } );' )
595+ lines += [f'if ({ var } ->{ ref } { self .c_name } )' ]
596+ lines += [f'{ self .nested_render_name } _free({ at } { var } ->{ ref } { self .c_name } );' ]
597+ return lines
583598
584599 def _attr_typol (self ):
585600 return f'.type = YNL_PT_NEST, .nest = &{ self .nested_render_name } _nest, '
@@ -632,15 +647,19 @@ def _complex_member_type(self, ri):
632647 def free_needs_iter (self ):
633648 return 'type' not in self .attr or self .attr ['type' ] == 'nest'
634649
635- def free (self , ri , var , ref ):
650+ def _free_lines (self , ri , var , ref ):
651+ lines = []
636652 if self .attr ['type' ] in scalars :
637- ri . cw . p ( f"free({ var } ->{ ref } { self .c_name } );" )
653+ lines += [ f"free({ var } ->{ ref } { self .c_name } );" ]
638654 elif 'type' not in self .attr or self .attr ['type' ] == 'nest' :
639- ri .cw .p (f"for (i = 0; i < { var } ->{ ref } n_{ self .c_name } ; i++)" )
640- ri .cw .p (f'{ self .nested_render_name } _free(&{ var } ->{ ref } { self .c_name } [i]);' )
641- ri .cw .p (f"free({ var } ->{ ref } { self .c_name } );" )
655+ lines += [
656+ f"for (i = 0; i < { var } ->{ ref } n_{ self .c_name } ; i++)" ,
657+ f'{ self .nested_render_name } _free(&{ var } ->{ ref } { self .c_name } [i]);' ,
658+ f"free({ var } ->{ ref } { self .c_name } );" ,
659+ ]
642660 else :
643661 raise Exception (f"Free of MultiAttr sub-type { self .attr ['type' ]} not supported yet" )
662+ return lines
644663
645664 def _attr_policy (self , policy ):
646665 return self .base_type ._attr_policy (policy )
@@ -666,8 +685,7 @@ def attr_put(self, ri, var):
666685 def _setter_lines (self , ri , member , presence ):
667686 # For multi-attr we have a count, not presence, hack up the presence
668687 presence = presence [:- (len ('_present.' ) + len (self .c_name ))] + "n_" + self .c_name
669- return [f"free({ member } );" ,
670- f"{ member } = { self .c_name } ;" ,
688+ return [f"{ member } = { self .c_name } ;" ,
671689 f"{ presence } = n_{ self .c_name } ;" ]
672690
673691
@@ -755,6 +773,7 @@ def __init__(self, family, space_name, type_list=None, inherited=None):
755773 self .request = False
756774 self .reply = False
757775 self .recursive = False
776+ self .in_multi_val = False # used by a MultiAttr or and legacy arrays
758777
759778 self .attr_list = []
760779 self .attrs = dict ()
@@ -1122,6 +1141,10 @@ def _load_nested_sets(self):
11221141 if attr in rs_members ['reply' ]:
11231142 self .pure_nested_structs [nested ].reply = True
11241143
1144+ if spec .is_multi_val ():
1145+ child = self .pure_nested_structs .get (nested )
1146+ child .in_multi_val = True
1147+
11251148 self ._sort_pure_types ()
11261149
11271150 # Propagate the request / reply / recursive
@@ -1136,6 +1159,8 @@ def _load_nested_sets(self):
11361159 struct .child_nests .update (child .child_nests )
11371160 child .request |= struct .request
11381161 child .reply |= struct .reply
1162+ if spec .is_multi_val ():
1163+ child .in_multi_val = True
11391164 if attr_set in struct .child_nests :
11401165 struct .recursive = True
11411166
@@ -2958,6 +2983,9 @@ def main():
29582983 for attr_set , struct in parsed .pure_nested_structs .items ():
29592984 ri = RenderInfo (cw , parsed , args .mode , "" , "" , attr_set )
29602985 print_type_full (ri , struct )
2986+ if struct .request and struct .in_multi_val :
2987+ free_rsp_nested_prototype (ri )
2988+ cw .nl ()
29612989
29622990 for op_name , op in parsed .ops .items ():
29632991 cw .p (f"/* ============== { op .enum_name } ============== */" )
0 commit comments