@@ -162,9 +162,15 @@ def _complex_member_type(self, ri):
162
162
def free_needs_iter (self ):
163
163
return False
164
164
165
- def free (self , ri , var , ref ):
165
+ def _free_lines (self , ri , var , ref ):
166
166
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 )
168
174
169
175
def arg_member (self , ri ):
170
176
member = self ._complex_member_type (ri )
@@ -263,6 +269,10 @@ def setter(self, ri, space, direction, deref=False, ref=None):
263
269
var = "req"
264
270
member = f"{ var } ->{ '.' .join (ref )} "
265
271
272
+ local_vars = []
273
+ if self .free_needs_iter ():
274
+ local_vars += ['unsigned int i;' ]
275
+
266
276
code = []
267
277
presence = ''
268
278
for i in range (0 , len (ref )):
@@ -272,14 +282,19 @@ def setter(self, ri, space, direction, deref=False, ref=None):
272
282
if i == len (ref ) - 1 and self .presence_type () != 'bit' :
273
283
continue
274
284
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 )
275
289
code += self ._setter_lines (ri , member , presence )
276
290
277
291
func_name = f"{ op_prefix (ri , direction , deref = deref )} _set_{ '_' .join (ref )} "
278
292
free = bool ([x for x in code if 'free(' in x ])
279
293
alloc = bool ([x for x in code if 'alloc(' in x ])
280
294
if free and not alloc :
281
295
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 ,
283
298
args = [f'{ type_name (ri , direction , deref = deref )} *{ var } ' ] + self .arg_member (ri ))
284
299
285
300
@@ -482,8 +497,7 @@ def _attr_get(self, ri, var):
482
497
['unsigned int len;' ]
483
498
484
499
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 } );" ,
487
501
f"{ member } = malloc({ presence } _len + 1);" ,
488
502
f'memcpy({ member } , { self .c_name } , { presence } _len);' ,
489
503
f'{ member } [{ presence } _len] = 0;' ]
@@ -536,8 +550,7 @@ def _attr_get(self, ri, var):
536
550
['unsigned int len;' ]
537
551
538
552
def _setter_lines (self , ri , member , presence ):
539
- return [f"free({ member } );" ,
540
- f"{ presence } _len = len;" ,
553
+ return [f"{ presence } _len = len;" ,
541
554
f"{ member } = malloc({ presence } _len);" ,
542
555
f'memcpy({ member } , { self .c_name } , { presence } _len);' ]
543
556
@@ -574,12 +587,14 @@ def is_recursive(self):
574
587
def _complex_member_type (self , ri ):
575
588
return self .nested_struct_type
576
589
577
- def free (self , ri , var , ref ):
590
+ def _free_lines (self , ri , var , ref ):
591
+ lines = []
578
592
at = '&'
579
593
if self .is_recursive_for_op (ri ):
580
594
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
583
598
584
599
def _attr_typol (self ):
585
600
return f'.type = YNL_PT_NEST, .nest = &{ self .nested_render_name } _nest, '
@@ -632,15 +647,19 @@ def _complex_member_type(self, ri):
632
647
def free_needs_iter (self ):
633
648
return 'type' not in self .attr or self .attr ['type' ] == 'nest'
634
649
635
- def free (self , ri , var , ref ):
650
+ def _free_lines (self , ri , var , ref ):
651
+ lines = []
636
652
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 } );" ]
638
654
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
+ ]
642
660
else :
643
661
raise Exception (f"Free of MultiAttr sub-type { self .attr ['type' ]} not supported yet" )
662
+ return lines
644
663
645
664
def _attr_policy (self , policy ):
646
665
return self .base_type ._attr_policy (policy )
@@ -666,8 +685,7 @@ def attr_put(self, ri, var):
666
685
def _setter_lines (self , ri , member , presence ):
667
686
# For multi-attr we have a count, not presence, hack up the presence
668
687
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 } ;" ,
671
689
f"{ presence } = n_{ self .c_name } ;" ]
672
690
673
691
@@ -755,6 +773,7 @@ def __init__(self, family, space_name, type_list=None, inherited=None):
755
773
self .request = False
756
774
self .reply = False
757
775
self .recursive = False
776
+ self .in_multi_val = False # used by a MultiAttr or and legacy arrays
758
777
759
778
self .attr_list = []
760
779
self .attrs = dict ()
@@ -1122,6 +1141,10 @@ def _load_nested_sets(self):
1122
1141
if attr in rs_members ['reply' ]:
1123
1142
self .pure_nested_structs [nested ].reply = True
1124
1143
1144
+ if spec .is_multi_val ():
1145
+ child = self .pure_nested_structs .get (nested )
1146
+ child .in_multi_val = True
1147
+
1125
1148
self ._sort_pure_types ()
1126
1149
1127
1150
# Propagate the request / reply / recursive
@@ -1136,6 +1159,8 @@ def _load_nested_sets(self):
1136
1159
struct .child_nests .update (child .child_nests )
1137
1160
child .request |= struct .request
1138
1161
child .reply |= struct .reply
1162
+ if spec .is_multi_val ():
1163
+ child .in_multi_val = True
1139
1164
if attr_set in struct .child_nests :
1140
1165
struct .recursive = True
1141
1166
@@ -2958,6 +2983,9 @@ def main():
2958
2983
for attr_set , struct in parsed .pure_nested_structs .items ():
2959
2984
ri = RenderInfo (cw , parsed , args .mode , "" , "" , attr_set )
2960
2985
print_type_full (ri , struct )
2986
+ if struct .request and struct .in_multi_val :
2987
+ free_rsp_nested_prototype (ri )
2988
+ cw .nl ()
2961
2989
2962
2990
for op_name , op in parsed .ops .items ():
2963
2991
cw .p (f"/* ============== { op .enum_name } ============== */" )
0 commit comments