[Xcb] [PATCH libxcb 6/6] generator: sumof of lists with varsized members
Christian Linhart
chris at demorecorder.com
Wed Sep 3 04:22:41 PDT 2014
Support sumof of lists with varsized members.
For these lists, iteration has to be done with iterators.
example:
<struct name="SumofTest_Element_Varsized">
<field type="CARD16" name="foo" />
<field type="CARD16" name="bar" />
<list type="CARD16" name="list1">
<fieldref>foo</fieldref>
</list>
</struct>
<struct name="SumofTest_FieldAccess_VarSized">
<field type="CARD32" name="len" />
<list type="SumofTest_Element_Varsized" name="mylist1">
<fieldref>len</fieldref>
</list>
<list type="CARD16" name="mylist2">
<sumof ref="mylist1">
<fieldref>bar</fieldref>
</sumof>
</list>
</struct>
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);
---
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 6169175..34b427e 100644
--- a/src/c_client.py
+++ b/src/c_client.py
@@ -1612,57 +1612,82 @@ def _c_accessor_get_expr(expr, field_mapping):
raise Exception("list field '%s' referenced by sumof not found" % expr.lenfield_name)
list_name = field_mapping[field.c_field_name][0]
c_length_func = "%s(%s)" % (field.c_length_name, list_name)
# note: xcb_sumof() has only been defined for integers
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
#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()
#compute the subexpression
rhs_expr_str = _c_accessor_get_expr(expr.rhs, scoped_field_mapping)
#resume with our code
_c_pre.start()
#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 )
_c_pre.end()
return sumvar;
#return 'xcb_sumof(%s, %s)' % (list_name, c_length_func)
elif expr.op != None:
--
2.0.1
More information about the Xcb
mailing list