generator: sumof of lists with varsized members ListInputDevices-V3
authorChristian Linhart <chris@demorecorder.com>
Wed, 3 Sep 2014 11:22:41 +0000 (13:22 +0200)
committerChristian Linhart <chris@demorecorder.com>
Tue, 9 Sep 2014 00:05:44 +0000 (02:05 +0200)
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);

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 <chris@DemoRecorder.com>
src/c_client.py

index ef5b5b6..6abe2a7 100644 (file)
@@ -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)