generator: support lists of structs which contain a switch
authorChristian Linhart <chris@demorecorder.com>
Thu, 21 Aug 2014 20:35:55 +0000 (22:35 +0200)
committerChristian Linhart <chris@demorecorder.com>
Mon, 20 Oct 2014 10:21:21 +0000 (12:21 +0200)
This essentially requires to have a correct sizeof-function
for the struct.
This in turn requires a sizeof-function for the switch, too.

Making a sizeof-function for the switch is triggered by
replacing "elif" by "if" in the first change of this patch.
This way, c_need_sizeof is also set to True for switches if appropriate.

The _c_serialize_helper_switch_field function has to support
the context "sizeof":
This is done in the second change of this patch

The third change of this patch fixes an alignment error:
It does not make sense to base the padding on the struct-type
which is generated for switch because this struct does not
represent the protocol. Rather it is the output of deserialization.
( The implicit padding for var-sized fields has other issues, IMHO,
but I am not touching these now...)

The effect on the generated code for the current xml-files
is as follows:
* several additional sizeof-functions are generated
* the fix of the alignment error only changes one place
  in the XKB-extension for the GetKbdByName-reply.
  This is no problem because that reply in its current form
  is broken/unfinished anyways.

Note:
This patch also fixes a problem in the generator when
a fixed-size list is the last field of a case or bitcase.

Message-ID: <1408653356-21191-2-git-send-email-chris@demorecorder.com>
Patch-Thread-Subject: [Xcb] xinput:QueryDeviceState: full-support: generator and xml-changes
Patch-Set: QueryDeviceState
Patch-Number: libxcb 2/3
Patch-Version: V1
Signed-off-by: Christian Linhart <chris@DemoRecorder.com>
Reviewed-By: Ran Benita <ran234@gmail.com>
src/c_client.py

index 6f8f8f2..1d1bbf6 100644 (file)
@@ -358,7 +358,8 @@ def _c_type_setup(self, name, postfix):
                 field.c_pointer = '*'
                 field.c_field_const_type = 'const ' + field.c_field_type
                 self.c_need_aux = True
-            elif not field.type.fixed_size() and not field.type.is_case_or_bitcase:
+
+            if not field.type.fixed_size() and not field.type.is_case_or_bitcase:
                 self.c_need_sizeof = True
 
             field.c_iterator_type = _t(field.field_type + ('iterator',))      # xcb_fieldtype_iterator_t
@@ -770,6 +771,10 @@ def _c_serialize_helper_switch_field(context, self, field, c_switch_variable, pr
     elif context in ('unserialize', 'unpack'):
         length = "%s(xcb_tmp, %s&%s%s)" % (field.type.c_unpack_name,
                                            c_field_names, prefix_str, field.c_field_name)
+    elif 'sizeof' == context:
+        # remove trailing ", " from c_field_names because it will be used at end of arglist
+        my_c_field_names = c_field_names[:-2]
+        length = "%s(xcb_tmp, %s)" % (field.type.c_sizeof_name, my_c_field_names)
 
     return length
 # _c_serialize_helper_switch_field()
@@ -1046,7 +1051,12 @@ def _c_serialize_helper_fields(context, self,
             code_lines.append('%s    xcb_parts_idx++;' % space)
             count += 1
 
-        code_lines.append('%s    xcb_align_to = ALIGNOF(%s);' % (space, 'char' if field.c_field_type == 'void' else field.c_field_type))
+        code_lines.append(
+            '%s    xcb_align_to = ALIGNOF(%s);'
+             % (space,
+                 'char'
+                  if field.c_field_type == 'void' or field.type.is_switch
+                  else field.c_field_type))
 
         need_padding = True
         if self.c_var_followed_by_fixed_fields: