From: Christian Linhart Date: Wed, 3 Sep 2014 11:22:41 +0000 (+0200) Subject: generator: sumof of lists with varsized members X-Git-Url: http://git.demorecorder.com/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f5ae4efe8c4a32c54b4f4be5cef1db197800f8d0;p=free-sw%2Fxcb%2Flibxcb 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 --- diff --git a/src/c_client.py b/src/c_client.py index ef5b5b6..6abe2a7 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)