[Xcb] [PATCH proto 1/2 V2] xcbgen: add support for implicit-padding

Christian Linhart chris at DemoRecorder.com
Wed Aug 27 03:35:01 PDT 2014


Add support for the optional attribute "implicit-padding".
The default value for this attribute is "true" because
this is the old behavior.

This attribute is supported for complex-types such as
struct, union, switch, case, bitcase, request, reply, event, error.

Also added a computation on whether a complex type
contains explicit alignpads or fixed-size pads.
This is stored in the member-variables
contains_explicit_alignpads and contains_fixedpads
Reason: This is needed by the generator for deciding
whether to declare variables that are needed for alignment.

V2: patch revised because the generator also needs to
know whether a struct contains fixed-size pads.
---
 xcbgen/xtypes.py | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/xcbgen/xtypes.py b/xcbgen/xtypes.py
index 45d7568..cef122e 100644
--- a/xcbgen/xtypes.py
+++ b/xcbgen/xtypes.py
@@ -19,14 +19,17 @@ class Type(object):
         nmemb is 1 for non-list types, None for variable-sized lists, otherwise number of elts.
         booleans for identifying subclasses, because I can't figure out isinstance().
         '''
         self.name = name
         self.size = None
         self.nmemb = None
         self.resolved = False
+        self.implicit_padding = True
+        self.contains_explicit_alignpads = False
+        self.contains_fixedpads = False
 
         # Screw isinstance().
         self.is_simple = False
         self.is_list = False
         self.is_expr = False
         self.is_container = False
         self.is_reply = False
@@ -308,14 +311,19 @@ class ComplexType(Type):
         for child in list(self.elt):
             if child.tag == 'pad':
                 field_name = 'pad' + str(module.pads)
                 fkey = 'CARD8'
                 type = PadType(child)
                 module.pads = module.pads + 1
                 visible = False
+                #Update contains_explicit_alignpads and contains_fixedpads
+                if type.align > 1:
+                    self.contains_explicit_alignpads = True
+                else:
+                    self.contains_fixedpads = True
             elif child.tag == 'field':
                 field_name = child.get('name')
                 enum = child.get('enum')
                 fkey = child.get('type')
                 type = module.get_type(fkey)
                 visible = True
             elif child.tag == 'exprfield':
@@ -395,14 +403,20 @@ class SwitchType(ComplexType):
         # whereas self.items contains the Bitcase objects themselves
         self.bitcases = []
 
         self.is_switch = True
         elts = list(elt)
         self.expr = Expression(elts[0] if len(elts) else elt, self)
 
+        #inherit implicit padding from parent if it is not overwritten
+        self.implicit_padding = elt.get(
+            'implicit-padding',
+            'true' if parents[0].implicit_padding else 'false'
+        ) == 'true'
+
     def resolve(self, module):
         if self.resolved:
             return
 
         parents = list(self.parents) + [self]
 
         # Resolve all of our field datatypes.
@@ -440,14 +454,20 @@ class SwitchType(ComplexType):
                         if field == _placeholder_byte:
                             self.fields[idx] = new_field
                             inserted = True
                             break
                     if False == inserted:
                         self.fields.append(new_field)
 
+                #Update contains_explicit_alignpads and contains_fixedpads
+                if type.contains_explicit_alignpads:
+                    self.contains_explicit_alignpads = True
+                if type.contains_fixedpads:
+                    self.contains_fixedpads = True
+
         self.calc_size() # Figure out how big we are
         self.resolved = True
 
     def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto, enum=None):
         if not self.fixed_size():
             # We need a length field.
             # Ask our Expression object for it's name, type, and whether it's on the wire.
@@ -485,14 +505,19 @@ class SwitchType(ComplexType):
 #        return True
 
 
 class Struct(ComplexType):
     '''
     Derived class representing a struct data type.
     '''
+
+    def __init__(self, name, elt):
+        ComplexType.__init__(self, name, elt)
+        self.implicit_padding = elt.get('implicit-padding', 'true') == 'true'
+
     out = __main__.output['struct']
 
 
 class Union(ComplexType):
     '''
     Derived class representing a union data type.
     '''
@@ -519,14 +544,21 @@ class CaseOrBitcaseType(ComplexType):
         ComplexType.__init__(self, name, fields)
         self.has_name = True
         self.index = 1
         self.lenfield_parent = list(parent) + [self]
         self.parents = list(parent)
         self.is_case_or_bitcase = True
 
+        #inherit implicit padding from parent if it is not overwritten
+        self.implicit_padding = elt.get(
+            'implicit-padding',
+            'true' if parent[0].implicit_padding else 'false'
+        ) == 'true'
+
+
     def make_member_of(self, module, switch_type, field_type, field_name, visible, wire, auto, enum=None):
         '''
         register BitcaseType with the corresponding SwitchType
 
         module is the global module object.
         complex_type is the structure object.
         see Field for the meaning of the other parameters.
@@ -573,14 +605,15 @@ class Reply(ComplexType):
     '''
     Derived class representing a reply.  Only found as a field of Request.
     '''
     def __init__(self, name, elt):
         ComplexType.__init__(self, name, elt)
         self.is_reply = True
         self.doc = None
+        self.implicit_padding = elt.get('implicit-padding', 'true') == 'true'
 
         for child in list(elt):
             if child.tag == 'doc':
                 self.doc = Doc(name, child)
 
     def resolve(self, module):
         if self.resolved:
@@ -604,14 +637,15 @@ class Request(ComplexType):
     opcode contains the request number.
     '''
     def __init__(self, name, elt):
         ComplexType.__init__(self, name, elt)
         self.reply = None
         self.doc = None
         self.opcode = elt.get('opcode')
+        self.implicit_padding = elt.get('implicit-padding', 'true') == 'true'
 
         for child in list(elt):
             if child.tag == 'reply':
                 self.reply = Reply(name, child)
             if child.tag == 'doc':
                 self.doc = Doc(name, child)
 
@@ -647,14 +681,16 @@ class Event(ComplexType):
         ComplexType.__init__(self, name, elt)
         self.opcodes = {}
 
         self.has_seq = not bool(elt.get('no-sequence-number'))
 
         self.is_ge_event = bool(elt.get('xge'))
 
+        self.implicit_padding = elt.get('implicit-padding', 'true') == 'true'
+
         self.doc = None
         for item in list(elt):
             if item.tag == 'doc':
                 self.doc = Doc(name, item)
 
     def add_opcode(self, opcode, name, main):
         self.opcodes[name] = opcode
@@ -695,14 +731,15 @@ class Error(ComplexType):
 
     Public fields added:
     opcodes is a dictionary of name -> opcode number, for errorcopies.
     '''
     def __init__(self, name, elt):
         ComplexType.__init__(self, name, elt)
         self.opcodes = {}
+        self.implicit_padding = elt.get('implicit-padding', 'true') == 'true'
 
     def add_opcode(self, opcode, name, main):
         self.opcodes[name] = opcode
         if main:
             self.name = name
 
     def resolve(self, module):
-- 
2.0.1


More information about the Xcb mailing list