@@ -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 )
@@ -654,10 +673,10 @@ def _attr_get(self, ri, var):
654
673
def attr_put (self , ri , var ):
655
674
if self .attr ['type' ] in scalars :
656
675
put_type = self .type
657
- ri .cw .p (f"for (unsigned int i = 0; i < { var } ->n_{ self .c_name } ; i++)" )
676
+ ri .cw .p (f"for (i = 0; i < { var } ->n_{ self .c_name } ; i++)" )
658
677
ri .cw .p (f"ynl_attr_put_{ put_type } (nlh, { self .enum_name } , { var } ->{ self .c_name } [i]);" )
659
678
elif 'type' not in self .attr or self .attr ['type' ] == 'nest' :
660
- ri .cw .p (f"for (unsigned int i = 0; i < { var } ->n_{ self .c_name } ; i++)" )
679
+ ri .cw .p (f"for (i = 0; i < { var } ->n_{ self .c_name } ; i++)" )
661
680
self ._attr_put_line (ri , var , f"{ self .nested_render_name } _put(nlh, " +
662
681
f"{ self .enum_name } , &{ var } ->{ self .c_name } [i])" )
663
682
else :
@@ -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
@@ -696,8 +714,11 @@ def _attr_typol(self):
696
714
def _attr_get (self , ri , var ):
697
715
local_vars = ['const struct nlattr *attr2;' ]
698
716
get_lines = [f'attr_{ self .c_name } = attr;' ,
699
- 'ynl_attr_for_each_nested(attr2, attr)' ,
700
- f'\t { var } ->n_{ self .c_name } ++;' ]
717
+ 'ynl_attr_for_each_nested(attr2, attr) {' ,
718
+ '\t if (ynl_attr_validate(yarg, attr2))' ,
719
+ '\t \t return YNL_PARSE_CB_ERROR;' ,
720
+ f'\t { var } ->n_{ self .c_name } ++;' ,
721
+ '}' ]
701
722
return get_lines , None , local_vars
702
723
703
724
@@ -755,6 +776,7 @@ def __init__(self, family, space_name, type_list=None, inherited=None):
755
776
self .request = False
756
777
self .reply = False
757
778
self .recursive = False
779
+ self .in_multi_val = False # used by a MultiAttr or and legacy arrays
758
780
759
781
self .attr_list = []
760
782
self .attrs = dict ()
@@ -1122,6 +1144,10 @@ def _load_nested_sets(self):
1122
1144
if attr in rs_members ['reply' ]:
1123
1145
self .pure_nested_structs [nested ].reply = True
1124
1146
1147
+ if spec .is_multi_val ():
1148
+ child = self .pure_nested_structs .get (nested )
1149
+ child .in_multi_val = True
1150
+
1125
1151
self ._sort_pure_types ()
1126
1152
1127
1153
# Propagate the request / reply / recursive
@@ -1136,6 +1162,8 @@ def _load_nested_sets(self):
1136
1162
struct .child_nests .update (child .child_nests )
1137
1163
child .request |= struct .request
1138
1164
child .reply |= struct .reply
1165
+ if spec .is_multi_val ():
1166
+ child .in_multi_val = True
1139
1167
if attr_set in struct .child_nests :
1140
1168
struct .recursive = True
1141
1169
@@ -1399,9 +1427,9 @@ def write_func_lvar(self, local_vars):
1399
1427
1400
1428
def write_func (self , qual_ret , name , body , args = None , local_vars = None ):
1401
1429
self .write_func_prot (qual_ret = qual_ret , name = name , args = args )
1430
+ self .block_start ()
1402
1431
self .write_func_lvar (local_vars = local_vars )
1403
1432
1404
- self .block_start ()
1405
1433
for line in body :
1406
1434
self .p (line )
1407
1435
self .block_end ()
@@ -1644,11 +1672,23 @@ def put_req_nested_prototype(ri, struct, suffix=';'):
1644
1672
1645
1673
1646
1674
def put_req_nested (ri , struct ):
1675
+ local_vars = []
1676
+ init_lines = []
1677
+
1678
+ local_vars .append ('struct nlattr *nest;' )
1679
+ init_lines .append ("nest = ynl_attr_nest_start(nlh, attr_type);" )
1680
+
1681
+ for _ , arg in struct .member_list ():
1682
+ if arg .presence_type () == 'count' :
1683
+ local_vars .append ('unsigned int i;' )
1684
+ break
1685
+
1647
1686
put_req_nested_prototype (ri , struct , suffix = '' )
1648
1687
ri .cw .block_start ()
1649
- ri .cw .write_func_lvar ('struct nlattr *nest;' )
1688
+ ri .cw .write_func_lvar (local_vars )
1650
1689
1651
- ri .cw .p ("nest = ynl_attr_nest_start(nlh, attr_type);" )
1690
+ for line in init_lines :
1691
+ ri .cw .p (line )
1652
1692
1653
1693
for _ , arg in struct .member_list ():
1654
1694
arg .attr_put (ri , "obj" )
@@ -1850,6 +1890,11 @@ def print_req(ri):
1850
1890
local_vars += ['size_t hdr_len;' ,
1851
1891
'void *hdr;' ]
1852
1892
1893
+ for _ , attr in ri .struct ["request" ].member_list ():
1894
+ if attr .presence_type () == 'count' :
1895
+ local_vars += ['unsigned int i;' ]
1896
+ break
1897
+
1853
1898
print_prototype (ri , direction , terminate = False )
1854
1899
ri .cw .block_start ()
1855
1900
ri .cw .write_func_lvar (local_vars )
@@ -2941,6 +2986,9 @@ def main():
2941
2986
for attr_set , struct in parsed .pure_nested_structs .items ():
2942
2987
ri = RenderInfo (cw , parsed , args .mode , "" , "" , attr_set )
2943
2988
print_type_full (ri , struct )
2989
+ if struct .request and struct .in_multi_val :
2990
+ free_rsp_nested_prototype (ri )
2991
+ cw .nl ()
2944
2992
2945
2993
for op_name , op in parsed .ops .items ():
2946
2994
cw .p (f"/* ============== { op .enum_name } ============== */" )
0 commit comments