From 2592873f1979fe372138f73b4ae43371d887f0e3 Mon Sep 17 00:00:00 2001 From: Christian Linhart Date: Wed, 3 Sep 2014 13:22:41 +0200 Subject: [PATCH] generator: sumof of lists with varsized members Support sumof of lists with varsized members. For these lists, iteration has to be done with iterators. example: foo len bar generated tempvar: int xcb_pre_tmp_1; /* sumof length */ int xcb_pre_tmp_2; /* sumof loop counter */ int64_t xcb_pre_tmp_3; /* sumof sum */ xcb_input_sumof_test_element_varsized_iterator_t xcb_pre_tmp_4; /* sumof list iterator */ generated code: /* mylist2 */ /* sumof start */ xcb_pre_tmp_1 = _aux->len; xcb_pre_tmp_3 = 0; xcb_pre_tmp_4 = xcb_input_sumof_test_field_access_var_sized_mylist_1_iterator(_aux); for ( xcb_pre_tmp_2 = 0; xcb_pre_tmp_2 < xcb_pre_tmp_1; xcb_pre_tmp_2++) { xcb_pre_tmp_3 += xcb_pre_tmp_4.data->bar; xcb_input_sumof_test_element_varsized_next(&xcb_pre_tmp_4); } /* sumof end. Result is in xcb_pre_tmp_3 */ xcb_block_len += xcb_pre_tmp_3 * sizeof(uint16_t); Message-ID: <1409743361-466-6-git-send-email-chris@demorecorder.com> Patch-Thread-Subject: [Xcb] xinput: make ListInputDevices work, sumof with nested expr, ... Patch-Set: ListInputDevices Patch-Number: libxcb 6/6 Patch-Version: V1 Signed-off-by: Christian Linhart --- src/c_client.py | 45 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/src/c_client.py b/src/c_client.py index ea7173f..75bf871 100644 --- a/src/c_client.py +++ b/src/c_client.py @@ -1616,27 +1616,43 @@ def _c_accessor_get_expr(expr, field_mapping): c_length_func = _c_accessor_get_expr(field.type.expr, field_mapping) #create explicit code for computing the sum. #This works for all C-types which can be added to int64_t with += + member_type = field.type.member + needs_iterator = not member_type.fixed_size() _c_pre.start() lengthvar = _c_pre.get_tempvarname() loopvar = _c_pre.get_tempvarname() sumvar = _c_pre.get_tempvarname() - listvar = _c_pre.get_tempvarname() + if needs_iterator: + iteratorvar = _c_pre.get_tempvarname() + else: + listvar = _c_pre.get_tempvarname() _c_pre.tempvar( "int %s; /* sumof length */", lengthvar ) _c_pre.tempvar( "int %s; /* sumof loop counter */", loopvar ) _c_pre.tempvar( "int64_t %s; /* sumof sum */", sumvar ) - _c_pre.tempvar( - "const %s* %s; /* sumof list ptr */", field.c_field_type, listvar ) + if needs_iterator: + _c_pre.tempvar( + "%s %s; /* sumof list iterator */", + field.c_iterator_type, iteratorvar ) + else: + _c_pre.tempvar( + "const %s* %s; /* sumof list ptr */", field.c_field_type, listvar ) _c_pre.code( "/* sumof start */" ) _c_pre.code( "%s = %s;", lengthvar, c_length_func ) _c_pre.code( "%s = 0;", sumvar ) - _c_pre.code( "%s = %s;", listvar, list_name ) + if needs_iterator: + _c_pre.code( "%s = %s;", iteratorvar, list_name ) + else: + _c_pre.code( "%s = %s;", listvar, list_name ) _c_pre.code( "for ( %s = 0; %s < %s; %s++) {", loopvar, loopvar, lengthvar, loopvar ) _c_pre.indent() if expr.rhs == None: - _c_pre.code( "%s += *%s;", sumvar, listvar ) + if needs_iterator: + _c_pre.code( "TODO" ) + else: + _c_pre.code( "%s += *%s;", sumvar, listvar ) else: #sumof has a nested expression which #has to be evaluated in the context of this list element @@ -1644,10 +1660,16 @@ def _c_accessor_get_expr(expr, field_mapping): #field mapping for the subexpression needs to include #the fields of the list-member type scoped_field_mapping = field_mapping.copy() - scoped_field_mapping.update( - _c_helper_field_mapping( - field.type.member, - [( listvar, '', field.type.member )] ) ) + if needs_iterator: + scoped_field_mapping.update( + _c_helper_field_mapping( + field.type.member, + [( iteratorvar + ".data", '', field.type.member )] ) ) + else: + scoped_field_mapping.update( + _c_helper_field_mapping( + field.type.member, + [( listvar, '', field.type.member )] ) ) #cause pre-code of the subexpression be added right here _c_pre.end() @@ -1658,7 +1680,10 @@ def _c_accessor_get_expr(expr, field_mapping): #output the summation expression _c_pre.code( "%s += %s;", sumvar, rhs_expr_str ) - _c_pre.code( "%s++;", listvar ); + if needs_iterator: + _c_pre.code( "%s(&%s);", field.type.c_next_name, iteratorvar ) + else: + _c_pre.code( "%s++;", listvar ); _c_pre.pop_indent() _c_pre.code( "}" ) _c_pre.code( "/* sumof end. Result is in %s */", sumvar ) -- 2.34.1