generator: support listelement-ref
[free-sw/xcb/libxcb] / src / c_client.py
index 5a41f9a..904bfce 100644 (file)
@@ -568,11 +568,6 @@ def _c_helper_fieldaccess_expr(prefix, field=None):
     last_sep =''
     for name, sep, obj in prefix:
         prefix_str += last_sep + name
-        if '' == sep:
-            sep = '->'
-            if ((obj.is_case_or_bitcase and obj.has_name) or     # named bitcase
-                (obj.is_switch and len(obj.parents)>1)):
-                sep = '.'
         last_sep = sep
 
     if field is None:
@@ -1595,12 +1590,7 @@ def _c_accessor_get_length(expr, field_mapping=None):
         if field_mapping is not None:
             lenfield_name = field_mapping[lenfield_name][0]
 
-    if expr.lenfield is not None and expr.lenfield.prev_varsized_field is not None:
-        # special case: variable and fixed size fields are intermixed
-        # if the lenfield is among the fixed size fields, there is no need
-        # to call a special accessor function like <expr.lenfield.c_accessor_name + '(' + prefix + ')'>
-        return field_mapping(expr.lenfield_name)
-    elif expr.lenfield_name is not None:
+    if expr.lenfield_name is not None:
         return lenfield_name
     else:
         return str(expr.nmemb)
@@ -1656,6 +1646,14 @@ def _c_accessor_get_expr(expr, field_mapping):
         _c_pre.code("for (%s = 0; %s < %s; %s++) {", loopvar, loopvar, lengthvar, loopvar)
         _c_pre.indent()
 
+        # define and set xcb_listelement, so that it can be used by
+        # listelement-ref expressions.
+        if expr.contains_listelement_ref:
+            _c_pre.code(
+                "const %s *xcb_listelement = %s;",
+                field.c_field_type, listvar)
+
+        # summation
         if expr.rhs is None:
             _c_pre.code("%s += *%s;", sumvar, listvar)
         else:
@@ -1665,10 +1663,11 @@ 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 not field.type.member.is_simple:
+                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()
@@ -1685,6 +1684,8 @@ def _c_accessor_get_expr(expr, field_mapping):
         _c_pre.code("/* sumof end. Result is in %s */", sumvar)
         _c_pre.end()
         return sumvar
+    elif expr.op == 'listelement-ref':
+        return '(*xcb_listelement)'
     elif expr.op != None:
         return ('(' + _c_accessor_get_expr(expr.lhs, field_mapping) +
                 ' ' + expr.op + ' ' +
@@ -3080,7 +3081,18 @@ def c_event(self, name):
                 force_packed = any(f.type.size == 8 and f.type.is_simple for f in self.fields[(idx+1):])
                 break
 
-    _c_type_setup(self, name, ('event',))
+    if self.name == name:
+        _c_type_setup(self, name, ('event',))
+        # generate accessors
+        # (needed for fields after var-sized fields, for lists with var-sized elements,
+        # switches, ...)
+        _c_accessors(self, name, name)
+    else:
+        # no type-setup needed for eventcopies
+        # (the type-setup of an eventcopy would overwrite members of the original
+        # event, and it would create sizeof-etc funtions which
+        # called undefined accessor functions)
+        pass
 
     # Opcode define
     _c_opcode(name, self.opcodes[name])
@@ -3093,6 +3105,22 @@ def c_event(self, name):
         _h('')
         _h('typedef %s %s;', _t(self.name + ('event',)), _t(name + ('event',)))
 
+        # Create sizeof-function for eventcopies for compatibility reasons
+        if self.c_need_sizeof:
+            _h_setlevel(1)
+            _c_setlevel(1)
+            _h('')
+            _h('int')
+            _h('%s (const void  *_buffer  /**< */);', _n(name + ('sizeof',)))
+            _c('')
+            _c('int')
+            _c('%s (const void  *_buffer  /**< */)', _n(name + ('sizeof',)))
+            _c('{');
+            _c('    return %s(_buffer);', _n(self.name + ('sizeof',)))
+            _c('}');
+            _h_setlevel(0)
+            _c_setlevel(0)
+
     _man_event(self, name)
 
 def c_error(self, name):