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

Christian Linhart chris at demorecorder.com
Thu Aug 21 13:32:00 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. This is stored in the
member-variable contains_explicit_alignpads.
Reason: This is needed by the generator for deciding
whether to declare variables that are needed for alignment.
---
 src/xcb.xsd      |  2 ++
 xcbgen/xtypes.py | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/src/xcb.xsd b/src/xcb.xsd
index 59bb9a8..1dccc30 100644
--- a/src/xcb.xsd
+++ b/src/xcb.xsd
@@ -202,14 +202,16 @@ authorization from the authors.
     <xsd:sequence>
       <xsd:group ref="fields" minOccurs="1" maxOccurs="unbounded" />
       <xsd:choice minOccurs="0" maxOccurs="1">
         <xsd:element ref="switch" />
       </xsd:choice>
     </xsd:sequence>
     <xsd:attribute name="name" type="xsd:string" use="required" />
+    <xsd:attribute name="implicit-padding" type="xsd:boolean"
+                             use="optional" default="true" />
   </xsd:complexType>
 
   <!-- Type for a packet structure -->
   <xsd:complexType name="packet-struct">
     <xsd:sequence>
       <xsd:group ref="fields" minOccurs="0" maxOccurs="unbounded" />
     </xsd:sequence>
diff --git a/xcbgen/xtypes.py b/xcbgen/xtypes.py
index 45d7568..cada61f 100644
--- a/xcbgen/xtypes.py
+++ b/xcbgen/xtypes.py
@@ -19,14 +19,16 @@ 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
 
         # Screw isinstance().
         self.is_simple = False
         self.is_list = False
         self.is_expr = False
         self.is_container = False
         self.is_reply = False
@@ -308,14 +310,17 @@ 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
+                if type.align > 1:
+                    self.contains_explicit_alignpads = 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 +400,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 +451,18 @@ 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
+                if type.contains_explicit_alignpads:
+                    self.contains_explicit_alignpads = 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 +500,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 +539,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 +600,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 +632,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 +676,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 +726,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