xv: Add align. pad in struct AdaptorInfo
[free-sw/xcb/proto] / xcbgen / xtypes.py
index 4836205..3cd9032 100644 (file)
@@ -1,7 +1,7 @@
 '''
 This module contains the classes which represent XCB data types.
 '''
-from expr import Field, Expression
+from xcbgen.expr import Field, Expression
 import __main__
 
 class Type(object):
@@ -56,7 +56,7 @@ class Type(object):
         '''
         raise Exception('abstract fixed_size method not overridden!')
 
-    def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto):
+    def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto, enum=None):
         '''
         Default method for making a data type a member of a structure.
         Extend this if the data type needs to add an additional length field or something.
@@ -65,7 +65,7 @@ class Type(object):
         complex_type is the structure object.
         see Field for the meaning of the other parameters.
         '''
-        new_field = Field(self, field_type, field_name, visible, wire, auto)
+        new_field = Field(self, field_type, field_name, visible, wire, auto, enum)
 
         # We dump the _placeholder_byte if any fields are added.
         for (idx, field) in enumerate(complex_type.fields):
@@ -75,6 +75,18 @@ class Type(object):
 
         complex_type.fields.append(new_field)
 
+    def make_fd_of(self, module, complex_type, fd_name):
+        '''
+        Method for making a fd member of a structure.
+        '''
+        new_fd = Field(self, module.get_type_name('INT32'), fd_name, True, False, False, None, True)
+        # We dump the _placeholder_byte if any fields are added.
+        for (idx, field) in enumerate(complex_type.fields):
+            if field == _placeholder_byte:
+                complex_type.fields[idx] = new_fd
+                return
+
+        complex_type.fields.append(new_fd)
 
 class SimpleType(Type):
     '''
@@ -103,9 +115,11 @@ class SimpleType(Type):
 tcard8 = SimpleType(('uint8_t',), 1)
 tcard16 = SimpleType(('uint16_t',), 2)
 tcard32 = SimpleType(('uint32_t',), 4)
+tcard64 = SimpleType(('uint64_t',), 8)
 tint8 =  SimpleType(('int8_t',), 1)
 tint16 = SimpleType(('int16_t',), 2)
 tint32 = SimpleType(('int32_t',), 4)
+tint64 = SimpleType(('int64_t',), 8)
 tchar =  SimpleType(('char',), 1)
 tfloat = SimpleType(('float',), 4)
 tdouble = SimpleType(('double',), 8)
@@ -123,7 +137,11 @@ class Enum(SimpleType):
         SimpleType.__init__(self, name, 4)
         self.values = []
         self.bits = []
+        self.doc = None
         for item in list(elt):
+            if item.tag == 'doc':
+                self.doc = Doc(name, item)
+
             # First check if we're using a default value
             if len(list(item)) == 0:
                 self.values.append((item.get('name'), ''))
@@ -159,7 +177,7 @@ class ListType(Type):
         Type.__init__(self, member.name)
         self.is_list = True
         self.member = member
-        self.parent = list(parent)
+        self.parents = list(parent)
 
         if elt.tag == 'list':
             elts = list(elt)
@@ -170,7 +188,7 @@ class ListType(Type):
         self.size = member.size if member.fixed_size() else None
         self.nmemb = self.expr.nmemb if self.expr.fixed_size() else None
 
-    def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto):
+    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.
@@ -180,7 +198,7 @@ class ListType(Type):
             needlen = True
 
             # See if the length field is already in the structure.
-            for parent in self.parent:
+            for parent in self.parents:
                 for field in parent.fields:
                     if field.field_name == lenfield_name:
                         needlen = False
@@ -189,21 +207,21 @@ class ListType(Type):
             if needlen:
                 type = module.get_type(lenfid)
                 lenfield_type = module.get_type_name(lenfid)
-                type.make_member_of(module, complex_type, lenfield_type, lenfield_name, True, lenwire, False)
+                type.make_member_of(module, complex_type, lenfield_type, lenfield_name, True, lenwire, False, enum)
 
         # Add ourself to the structure by calling our original method.
-        Type.make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto)
+        Type.make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto, enum)
 
     def resolve(self, module):
         if self.resolved:
             return
         self.member.resolve(module)
-        self.expr.resolve(module, self.parent)
+        self.expr.resolve(module, self.parents)
 
         # Find my length field again.  We need the actual Field object in the expr.
         # This is needed because we might have added it ourself above.
         if not self.fixed_size():
-            for parent in self.parent:
+            for parent in self.parents:
                 for field in parent.fields:
                     if field.field_name == self.expr.lenfield_name and field.wire:
                         self.expr.lenfield = field
@@ -221,11 +239,11 @@ class ExprType(Type):
     Public fields added:
     expr is an Expression object containing the value of the field.
     '''
-    def __init__(self, elt, member, *parent):
+    def __init__(self, elt, member, *parents):
         Type.__init__(self, member.name)
         self.is_expr = True
         self.member = member
-        self.parent = parent
+        self.parents = parents
 
         self.expr = Expression(list(elt)[0], self)
 
@@ -249,13 +267,17 @@ class PadType(Type):
         Type.__init__(self, tcard8.name)
         self.is_pad = True
         self.size = 1
-        self.nmemb = 1 if (elt == None) else int(elt.get('bytes'), 0)
+        self.nmemb = 1
+        self.align = 1
+        if elt != None:
+            self.nmemb = int(elt.get('bytes', "1"), 0)
+            self.align = int(elt.get('align', "1"), 0)
 
     def resolve(self, module):
         self.resolved = True
 
     def fixed_size(self):
-        return True
+        return self.align <= 1
 
     
 class ComplexType(Type):
@@ -273,22 +295,24 @@ class ComplexType(Type):
         self.nmemb = 1
         self.size = 0
         self.lenfield_parent = [self]
+        self.fds = []
 
     def resolve(self, module):
         if self.resolved:
             return
-        pads = 0
+        enum = None
 
         # Resolve all of our field datatypes.
         for child in list(self.elt):
             if child.tag == 'pad':
-                field_name = 'pad' + str(pads)
+                field_name = 'pad' + str(module.pads)
                 fkey = 'CARD8'
                 type = PadType(child)
-                pads = pads + 1
+                module.pads = module.pads + 1
                 visible = False
             elif child.tag == 'field':
                 field_name = child.get('name')
+                enum = child.get('enum')
                 fkey = child.get('type')
                 type = module.get_type(fkey)
                 visible = True
@@ -316,14 +340,19 @@ class ComplexType(Type):
                 type.make_member_of(module, self, field_type, field_name, visible, True, False)
                 type.resolve(module)
                 continue
+            elif child.tag == 'fd':
+                fd_name = child.get('name')
+                type = module.get_type('INT32')
+                type.make_fd_of(module, self, fd_name)
+                continue
             else:
                 # Hit this on Reply
-                continue 
+                continue
 
             # Get the full type name for the field
             field_type = module.get_type_name(fkey)
             # Add the field to ourself
-            type.make_member_of(module, self, field_type, field_name, visible, True, False)
+            type.make_member_of(module, self, field_type, field_name, visible, True, False, enum)
             # Recursively resolve the type (could be another structure, list)
             type.resolve(module)
 
@@ -357,7 +386,7 @@ class SwitchType(ComplexType):
 
     def __init__(self, name, elt, *parents):
         ComplexType.__init__(self, name, elt)
-        self.parent = parents
+        self.parents = parents
         # FIXME: switch cannot store lenfields, so it should just delegate the parents
         self.lenfield_parent = list(parents) + [self]
         # self.fields contains all possible fields collected from the Bitcase objects, 
@@ -371,9 +400,8 @@ class SwitchType(ComplexType):
     def resolve(self, module):
         if self.resolved:
             return
-#        pads = 0
 
-        parents = list(self.parent) + [self]
+        parents = list(self.parents) + [self]
 
         # Resolve all of our field datatypes.
         for index, child in enumerate(list(self.elt)):
@@ -413,8 +441,7 @@ class SwitchType(ComplexType):
         self.calc_size() # Figure out how big we are
         self.resolved = True
 
-    # FIXME: really necessary for Switch??
-    def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto):
+    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.
@@ -424,7 +451,7 @@ class SwitchType(ComplexType):
             needlen = True
 
             # See if the length field is already in the structure.
-            for parent in self.parent:
+            for parent in self.parents:
                 for field in parent.fields:
                     if field.field_name == lenfield_name:
                         needlen = False
@@ -433,10 +460,10 @@ class SwitchType(ComplexType):
             if needlen:
                 type = module.get_type(lenfid)
                 lenfield_type = module.get_type_name(lenfid)
-                type.make_member_of(module, complex_type, lenfield_type, lenfield_name, True, lenwire, False)
+                type.make_member_of(module, complex_type, lenfield_type, lenfield_name, True, lenwire, False, enum)
 
         # Add ourself to the structure by calling our original method.
-        Type.make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto)
+        Type.make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto, enum)
 
     # size for switch can only be calculated at runtime
     def calc_size(self):
@@ -476,15 +503,21 @@ class BitcaseType(ComplexType):
     '''
     def __init__(self, index, name, elt, *parent):
         elts = list(elt)
-        self.expr = Expression(elts[0] if len(elts) else elt, self)
-        ComplexType.__init__(self, name, elts[1:])        
+        self.expr = []
+        fields = []
+        for elt in elts:
+            if elt.tag == 'enumref':
+                self.expr.append(Expression(elt, self))
+            else:
+                fields.append(elt)
+        ComplexType.__init__(self, name, fields)
         self.has_name = True
         self.index = 1
         self.lenfield_parent = list(parent) + [self]
         self.parents = list(parent)
         self.is_bitcase = True
 
-    def make_member_of(self, module, switch_type, field_type, field_name, visible, wire, auto):
+    def make_member_of(self, module, switch_type, field_type, field_name, visible, wire, auto, enum=None):
         '''
         register BitcaseType with the corresponding SwitchType
 
@@ -492,7 +525,7 @@ class BitcaseType(ComplexType):
         complex_type is the structure object.
         see Field for the meaning of the other parameters.
         '''
-        new_field = Field(self, field_type, field_name, visible, wire, auto)
+        new_field = Field(self, field_type, field_name, visible, wire, auto, enum)
 
         # We dump the _placeholder_byte if any bitcases are added.
         for (idx, field) in enumerate(switch_type.bitcases):
@@ -505,8 +538,9 @@ class BitcaseType(ComplexType):
     def resolve(self, module):
         if self.resolved:
             return
-        
-        self.expr.resolve(module, self.parents+[self])
+
+        for e in self.expr:
+            e.resolve(module, self.parents+[self])
 
         # Resolve the bitcase expression
         ComplexType.resolve(self, module)
@@ -519,10 +553,17 @@ class Reply(ComplexType):
     def __init__(self, name, elt):
         ComplexType.__init__(self, name, elt)
         self.is_reply = True
+        self.doc = None
+
+        for child in list(elt):
+            if child.tag == 'doc':
+                self.doc = Doc(name, child)
 
     def resolve(self, module):
         if self.resolved:
             return
+        # Reset pads count
+        module.pads = 0
         # Add the automatic protocol fields
         self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))
         self.fields.append(_placeholder_byte)
@@ -542,11 +583,14 @@ class Request(ComplexType):
     def __init__(self, name, elt):
         ComplexType.__init__(self, name, elt)
         self.reply = None
+        self.doc = None
         self.opcode = elt.get('opcode')
 
         for child in list(elt):
             if child.tag == 'reply':
                 self.reply = Reply(name, child)
+            if child.tag == 'doc':
+                self.doc = Doc(name, child)
 
     def resolve(self, module):
         if self.resolved:
@@ -580,23 +624,43 @@ class Event(ComplexType):
         ComplexType.__init__(self, name, elt)
         self.opcodes = {}
 
-        tmp = elt.get('no-sequence-number')
-        self.has_seq = (tmp == None or tmp.lower() == 'false' or tmp == '0')
-            
+        self.has_seq = not bool(elt.get('no-sequence-number'))
+
+        self.is_ge_event = bool(elt.get('xge'))
+
+        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
         if main:
             self.name = name
 
     def resolve(self, module):
+        def add_event_header():
+            self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))
+            if self.has_seq:
+                self.fields.append(_placeholder_byte)
+                self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True))
+
+        def add_ge_event_header():
+            self.fields.append(Field(tcard8,  tcard8.name,  'response_type', False, True, True))
+            self.fields.append(Field(tcard8,  tcard8.name,  'extension', False, True, True))
+            self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True))
+            self.fields.append(Field(tcard32, tcard32.name, 'length', False, True, True))
+            self.fields.append(Field(tcard16, tcard16.name, 'event_type', False, True, True))
+
         if self.resolved:
             return
 
         # Add the automatic protocol fields
-        self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))
-        if self.has_seq:
-            self.fields.append(_placeholder_byte)
-            self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True))
+        if self.is_ge_event:
+            add_ge_event_header()
+        else:
+            add_event_header()
+
         ComplexType.resolve(self, module)
 
     out = __main__.output['event']
@@ -630,4 +694,35 @@ class Error(ComplexType):
 
     out = __main__.output['error']
 
+
+class Doc(object):
+    '''
+    Class representing a <doc> tag.
+    '''
+    def __init__(self, name, elt):
+        self.name = name
+        self.description = None
+        self.brief = 'BRIEF DESCRIPTION MISSING'
+        self.fields = {}
+        self.errors = {}
+        self.see = {}
+        self.example = None
+
+        for child in list(elt):
+            text = child.text if child.text else ''
+            if child.tag == 'description':
+                self.description = text.strip()
+            if child.tag == 'brief':
+                self.brief = text.strip()
+            if child.tag == 'field':
+                self.fields[child.get('name')] = text.strip()
+            if child.tag == 'error':
+                self.errors[child.get('type')] = text.strip()
+            if child.tag == 'see':
+                self.see[child.get('name')] = child.get('type')
+            if child.tag == 'example':
+                self.example = text.strip()
+
+
+
 _placeholder_byte = Field(PadType(None), tcard8.name, 'pad0', False, True, False)