X-Git-Url: http://git.demorecorder.com/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fc_client.py;h=ad3ea22ea38462de8ba2f18edc364b35d2dd6947;hb=b12038e9ae5343c4176f11d68c963c752bc35c03;hp=1f3277a9034022493747cdfc9ac6d3a5bd006e50;hpb=29cca33b9001961fa2c33bb9d9fe4a9983913fce;p=free-sw%2Fxcb%2Flibxcb diff --git a/src/c_client.py b/src/c_client.py index 1f3277a..ad3ea22 100644 --- a/src/c_client.py +++ b/src/c_client.py @@ -1,6 +1,7 @@ #!/usr/bin/env python from xml.etree.cElementTree import * from os.path import basename +from functools import reduce import getopt import sys import re @@ -170,9 +171,13 @@ def c_open(self): _c('#include ') _c('#include ') _c('#include ') + _c('#include /* for offsetof() */') _c('#include "xcbext.h"') _c('#include "%s.h"', _ns.header) + _c('') + _c('#define ALIGNOF(type) offsetof(struct { char dummy; type member; }, member)') + if _ns.is_ext: for (n, h) in self.imports: _hc('#include "%s.h"', h) @@ -323,7 +328,7 @@ def _c_type_setup(self, name, postfix): field.c_field_type = _t(field.field_type) field.c_field_const_type = ('' if field.type.nmemb == 1 else 'const ') + field.c_field_type field.c_field_name = _cpp(field.field_name) - field.c_subscript = '[%d]' % field.type.nmemb if (field.type.nmemb > 1) else '' + field.c_subscript = '[%d]' % field.type.nmemb if (field.type.nmemb and field.type.nmemb > 1) else '' field.c_pointer = ' ' if field.type.nmemb == 1 else '*' # correct the c_pointer field for variable size non-list types @@ -443,7 +448,7 @@ def _c_helper_field_mapping(complex_type, prefix, flat=False): else: for f in complex_type.fields: fname = _c_helper_absolute_name(prefix, f) - if all_fields.has_key(f.field_name): + if f.field_name in all_fields: raise Exception("field name %s has been registered before" % f.field_name) all_fields[f.field_name] = (fname, f) @@ -524,7 +529,7 @@ def get_expr_fields(self): prefix.append(('', '', self)) all_fields = _c_helper_resolve_field_names (prefix) - resolved_fields_names = filter(lambda x: x in all_fields.keys(), unresolved_fields_names) + resolved_fields_names = list(filter(lambda x: x in all_fields.keys(), unresolved_fields_names)) if len(unresolved_fields_names) != len(resolved_fields_names): raise Exception("could not resolve all fields for %s" % self.name) @@ -636,7 +641,7 @@ def get_serialize_params(context, self, buffer_var='_buffer', aux_var='_aux'): def _c_serialize_helper_insert_padding(context, code_lines, space, postpone): code_lines.append('%s /* insert padding */' % space) - code_lines.append('%s xcb_pad = -xcb_block_len & 3;' % space) + code_lines.append('%s xcb_pad = -xcb_block_len & (xcb_align_to - 1);' % space) # code_lines.append('%s printf("automatically inserting padding: %%%%d\\n", xcb_pad);' % space) code_lines.append('%s xcb_buffer_len += xcb_block_len + xcb_pad;' % space) @@ -743,8 +748,8 @@ def _c_serialize_helper_list_field(context, self, field, param_names = [p[2] for p in params] expr_fields_names = [f.field_name for f in get_expr_fields(field.type)] - resolved = filter(lambda x: x in param_names, expr_fields_names) - unresolved = filter(lambda x: x not in param_names, expr_fields_names) + resolved = list(filter(lambda x: x in param_names, expr_fields_names)) + unresolved = list(filter(lambda x: x not in param_names, expr_fields_names)) field_mapping = {} for r in resolved: @@ -757,8 +762,8 @@ def _c_serialize_helper_list_field(context, self, field, field.c_field_name) field_mapping.update(_c_helper_resolve_field_names(prefix)) - resolved += filter(lambda x: x in field_mapping, unresolved) - unresolved = filter(lambda x: x not in field_mapping, unresolved) + resolved += list(filter(lambda x: x in field_mapping, unresolved)) + unresolved = list(filter(lambda x: x not in field_mapping, unresolved)) if len(unresolved)>0: raise Exception('could not resolve the length fields required for list %s' % field.c_field_name) @@ -925,8 +930,9 @@ def _c_serialize_helper_fields(context, self, prev_field_was_variable = False for field in self.fields: - if not ((field.wire and not field.auto) or field.visible): - continue + if not field.visible: + if not ((field.wire and not field.auto) or 'unserialize' == context): + continue # switch/bitcase: fixed size fields must be considered explicitly if field.type.fixed_size(): @@ -991,6 +997,8 @@ 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)) + need_padding = True if self.var_followed_by_fixed_fields: need_padding = False @@ -1082,7 +1090,7 @@ def _c_serialize(context, self): param_str.append("%s%s%s %s%s /**< */" % (indent, typespec, spacing, pointerspec, field_name)) # insert function name param_str[0] = "%s (%s" % (func_name, param_str[0].strip()) - param_str = map(lambda x: "%s," % x, param_str) + param_str = list(map(lambda x: "%s," % x, param_str)) for s in param_str[:-1]: _hc(s) _h("%s);" % param_str[-1].rstrip(',')) @@ -1098,9 +1106,11 @@ def _c_serialize(context, self): _c(' %s *xcb_out = *_buffer;', self.c_type) _c(' unsigned int xcb_out_pad = -sizeof(%s) & 3;', self.c_type) _c(' unsigned int xcb_buffer_len = sizeof(%s) + xcb_out_pad;', self.c_type) + _c(' unsigned int xcb_align_to;') else: _c(' char *xcb_out = *_buffer;') _c(' unsigned int xcb_buffer_len = 0;') + _c(' unsigned int xcb_align_to;') prefix = [('_aux', '->', self)] aux_ptr = 'xcb_out' @@ -1123,6 +1133,7 @@ def _c_serialize(context, self): _c(' unsigned int xcb_buffer_len = 0;') _c(' unsigned int xcb_block_len = 0;') _c(' unsigned int xcb_pad = 0;') + _c(' unsigned int xcb_align_to;') elif 'sizeof' == context: param_names = [p[2] for p in params] @@ -1158,7 +1169,7 @@ def _c_serialize(context, self): if not (self.is_switch or self.var_followed_by_fixed_fields): # look if we have to declare an '_aux' variable at all - if len(filter(lambda x: x.find('_aux')!=-1, code_lines))>0: + if len(list(filter(lambda x: x.find('_aux')!=-1, code_lines)))>0: if not self.var_followed_by_fixed_fields: _c(' const %s *_aux = (%s *)_buffer;', self.c_type, self.c_type) else: @@ -1167,6 +1178,7 @@ def _c_serialize(context, self): _c(' unsigned int xcb_buffer_len = 0;') _c(' unsigned int xcb_block_len = 0;') _c(' unsigned int xcb_pad = 0;') + _c(' unsigned int xcb_align_to;') _c('') for t in temp_vars: @@ -1422,6 +1434,11 @@ def _c_accessor_get_expr(expr, field_mapping): else: return lenexp +def type_pad_type(type): + if type == 'void': + return 'char' + return type + def _c_accessors_field(self, field): ''' Declares the accessor functions for a non-list field that follows a variable-length field. @@ -1456,7 +1473,7 @@ def _c_accessors_field(self, field): else: _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R')) _c(' return * (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index) + %d);', - field.c_field_type, field.first_field_after_varsized.type.c_type, field.prev_varsized_offset) + field.c_field_type, type_pad_type(field.first_field_after_varsized.type.c_type), field.prev_varsized_offset) _c('}') else: _hc('') @@ -1487,7 +1504,7 @@ def _c_accessors_field(self, field): else: _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R')) _c(' return (%s) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index) + %d);', - return_type, field.first_field_after_varsized.type.c_type, field.prev_varsized_offset) + return_type, type_pad_type(field.first_field_after_varsized.type.c_type), field.prev_varsized_offset) _c('}') @@ -1574,7 +1591,7 @@ def _c_accessors_list(self, field): else: _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R')) _c(' return (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index) + %d);', - field.c_field_type, field.first_field_after_varsized.type.c_type, field.prev_varsized_offset) + field.c_field_type, type_pad_type(field.first_field_after_varsized.type.c_type), field.prev_varsized_offset) _c('}') _hc('') @@ -1678,7 +1695,7 @@ def _c_accessors_list(self, field): else: _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R')) _c(' i.data = (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index));', - field.c_field_type, field.c_field_type) + field.c_field_type, type_pad_type(field.c_field_type)) if switch_obj is None: _c(' i.rem = %s;', _c_accessor_get_expr(field.type.expr, fields)) _c(' i.index = (char *) i.data - (char *) %s;', 'R' if switch_obj is None else 'S' ) @@ -2276,26 +2293,26 @@ output = {'open' : c_open, # Check for the argument that specifies path to the xcbgen python package. try: opts, args = getopt.getopt(sys.argv[1:], 'p:') -except getopt.GetoptError, err: - print str(err) - print 'Usage: c_client.py [-p path] file.xml' +except getopt.GetoptError as err: + print(err) + print('Usage: c_client.py [-p path] file.xml') sys.exit(1) for (opt, arg) in opts: if opt == '-p': - sys.path.append(arg) + sys.path.insert(1, arg) # Import the module class try: from xcbgen.state import Module except ImportError: - print '' - print 'Failed to load the xcbgen Python package!' - print 'Make sure that xcb/proto installed it on your Python path.' - print 'If not, you will need to create a .pth file or define $PYTHONPATH' - print 'to extend the path.' - print 'Refer to the README file in xcb/proto for more info.' - print '' + print(''' +Failed to load the xcbgen Python package! +Make sure that xcb/proto installed it on your Python path. +If not, you will need to create a .pth file or define $PYTHONPATH +to extend the path. +Refer to the README file in xcb/proto for more info. +''') raise # Parse the xml header