generator: support lists of structs which contain a switch

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>
This commit is contained in:
Christian Linhart 2014-08-21 22:35:55 +02:00
parent d74d066949
commit 277ea629de

View File

@ -358,7 +358,8 @@ def _c_type_setup(self, name, postfix):
field.c_pointer = '*' field.c_pointer = '*'
field.c_field_const_type = 'const ' + field.c_field_type field.c_field_const_type = 'const ' + field.c_field_type
self.c_need_aux = True 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 self.c_need_sizeof = True
field.c_iterator_type = _t(field.field_type + ('iterator',)) # xcb_fieldtype_iterator_t 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'): elif context in ('unserialize', 'unpack'):
length = "%s(xcb_tmp, %s&%s%s)" % (field.type.c_unpack_name, length = "%s(xcb_tmp, %s&%s%s)" % (field.type.c_unpack_name,
c_field_names, prefix_str, field.c_field_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 return length
# _c_serialize_helper_switch_field() # _c_serialize_helper_switch_field()
@ -1046,7 +1051,12 @@ def _c_serialize_helper_fields(context, self,
code_lines.append('%s xcb_parts_idx++;' % space) code_lines.append('%s xcb_parts_idx++;' % space)
count += 1 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 need_padding = True
if self.c_var_followed_by_fixed_fields: if self.c_var_followed_by_fixed_fields: