diff options
Diffstat (limited to 'libxcb/xcb-proto/xcbgen')
-rw-r--r-- | libxcb/xcb-proto/xcbgen/expr.py | 256 | ||||
-rw-r--r-- | libxcb/xcb-proto/xcbgen/xtypes.py | 72 |
2 files changed, 190 insertions, 138 deletions
diff --git a/libxcb/xcb-proto/xcbgen/expr.py b/libxcb/xcb-proto/xcbgen/expr.py index bbc5a3fd7..4f8af6f83 100644 --- a/libxcb/xcb-proto/xcbgen/expr.py +++ b/libxcb/xcb-proto/xcbgen/expr.py @@ -1,127 +1,129 @@ -'''
-This module contains helper classes for structure fields and length expressions.
-'''
-class Field(object):
- '''
- Represents a field of a structure.
-
- type is the datatype object for the field.
- field_type is the name of the type (string tuple)
- field_name is the name of the structure field.
- visible is true iff the field should be in the request API.
- wire is true iff the field should be in the request structure.
- auto is true iff the field is on the wire but not in the request API (e.g. opcode)
- '''
- def __init__(self, type, field_type, field_name, visible, wire, auto):
- self.type = type
- self.field_type = field_type
- self.field_name = field_name
- self.visible = visible
- self.wire = wire
- self.auto = auto
-
-
-class Expression(object):
- '''
- Represents a mathematical expression for a list length or exprfield.
-
- Public fields:
- op is the operation (text +,*,/,<<,~) or None.
- lhs and rhs are the sub-Expressions if op is set.
- lenfield_name is the name of the length field, or None for request lists.
- lenfield is the Field object for the length field, or None.
- bitfield is True if the length field is a bitmask instead of a number.
- nmemb is the fixed size (value)of the expression, or None
- '''
- def __init__(self, elt, parent):
- self.parent = parent
-
- self.nmemb = None
-
- self.lenfield_name = None
- self.lenfield_type = None
- self.lenfield_parent = None
- self.lenfield = None
- self.lenwire = False
- self.bitfield = False
-
- self.op = None
- self.lhs = None
- self.rhs = None
-
- if elt.tag == 'list':
- # List going into a request, which has no length field (inferred by server)
- self.lenfield_name = elt.get('name') + '_len'
- self.lenfield_type = 'CARD32'
-
- elif elt.tag == 'fieldref':
- # Standard list with a fieldref
- self.lenfield_name = elt.text
-
- elif elt.tag == 'valueparam':
- # Value-mask. The length bitmask is described by attributes.
- self.lenfield_name = elt.get('value-mask-name')
- self.lenfield_type = elt.get('value-mask-type')
- self.lenwire = True
- self.bitfield = True
-
- elif elt.tag == 'op':
- # Op field. Need to recurse.
- self.op = elt.get('op')
- self.lhs = Expression(list(elt)[0], parent)
- self.rhs = Expression(list(elt)[1], parent)
-
- # Hopefully we don't have two separate length fields...
- self.lenfield_name = self.lhs.lenfield_name
- if self.lenfield_name == None:
- self.lenfield_name = self.rhs.lenfield_name
-
- elif elt.tag == 'unop':
- # Op field. Need to recurse.
- self.op = elt.get('op')
- self.rhs = Expression(list(elt)[0], parent)
-
- self.lenfield_name = self.rhs.lenfield_name
-
- elif elt.tag == 'value':
- # Constant expression
- self.nmemb = int(elt.text, 0)
-
- elif elt.tag == 'popcount':
- self.op = 'popcount'
- self.rhs = Expression(list(elt)[0], parent)
- self.lenfield_name = self.rhs.lenfield_name
- # xcb_popcount returns 'int' - handle the type in the language-specific part
-
- elif elt.tag == 'enumref':
- self.op = 'enumref'
- self.lenfield_name = (elt.get('ref'), elt.text)
-
- elif elt.tag == 'sumof':
- self.op = 'sumof'
- self.lenfield_name = elt.get('ref')
-
- else:
- # Notreached
- raise Exception("undefined tag '%s'" % elt.tag)
-
- def fixed_size(self):
- return self.nmemb != None
-
- def resolve(self, module, parents):
- if self.op == 'enumref':
- self.lenfield_type = module.get_type(self.lenfield_name[0])
- self.lenfield_name = self.lenfield_name[1]
- elif self.op == 'sumof':
- # need to find the field with lenfield_name
- for p in reversed(parents):
- fields = dict([(f.field_name, f) for f in p.fields])
- if self.lenfield_name in fields.keys():
- if p.is_bitcase:
- # switch is the anchestor
- self.lenfield_parent = p.parents[-1]
- else:
- self.lenfield_parent = p
- self.lenfield_type = fields[self.lenfield_name].field_type
- break
-
+''' +This module contains helper classes for structure fields and length expressions. +''' +class Field(object): + ''' + Represents a field of a structure. + + type is the datatype object for the field. + field_type is the name of the type (string tuple) + field_name is the name of the structure field. + visible is true iff the field should be in the request API. + wire is true iff the field should be in the request structure. + auto is true iff the field is on the wire but not in the request API (e.g. opcode) + enum is the enum name this field refers to, if any. + ''' + def __init__(self, type, field_type, field_name, visible, wire, auto, enum=None): + self.type = type + self.field_type = field_type + self.field_name = field_name + self.enum = enum + self.visible = visible + self.wire = wire + self.auto = auto + + +class Expression(object): + ''' + Represents a mathematical expression for a list length or exprfield. + + Public fields: + op is the operation (text +,*,/,<<,~) or None. + lhs and rhs are the sub-Expressions if op is set. + lenfield_name is the name of the length field, or None for request lists. + lenfield is the Field object for the length field, or None. + bitfield is True if the length field is a bitmask instead of a number. + nmemb is the fixed size (value)of the expression, or None + ''' + def __init__(self, elt, parent): + self.parent = parent + + self.nmemb = None + + self.lenfield_name = None + self.lenfield_type = None + self.lenfield_parent = None + self.lenfield = None + self.lenwire = False + self.bitfield = False + + self.op = None + self.lhs = None + self.rhs = None + + if elt.tag == 'list': + # List going into a request, which has no length field (inferred by server) + self.lenfield_name = elt.get('name') + '_len' + self.lenfield_type = 'CARD32' + + elif elt.tag == 'fieldref': + # Standard list with a fieldref + self.lenfield_name = elt.text + + elif elt.tag == 'valueparam': + # Value-mask. The length bitmask is described by attributes. + self.lenfield_name = elt.get('value-mask-name') + self.lenfield_type = elt.get('value-mask-type') + self.lenwire = True + self.bitfield = True + + elif elt.tag == 'op': + # Op field. Need to recurse. + self.op = elt.get('op') + self.lhs = Expression(list(elt)[0], parent) + self.rhs = Expression(list(elt)[1], parent) + + # Hopefully we don't have two separate length fields... + self.lenfield_name = self.lhs.lenfield_name + if self.lenfield_name == None: + self.lenfield_name = self.rhs.lenfield_name + + elif elt.tag == 'unop': + # Op field. Need to recurse. + self.op = elt.get('op') + self.rhs = Expression(list(elt)[0], parent) + + self.lenfield_name = self.rhs.lenfield_name + + elif elt.tag == 'value': + # Constant expression + self.nmemb = int(elt.text, 0) + + elif elt.tag == 'popcount': + self.op = 'popcount' + self.rhs = Expression(list(elt)[0], parent) + self.lenfield_name = self.rhs.lenfield_name + # xcb_popcount returns 'int' - handle the type in the language-specific part + + elif elt.tag == 'enumref': + self.op = 'enumref' + self.lenfield_name = (elt.get('ref'), elt.text) + + elif elt.tag == 'sumof': + self.op = 'sumof' + self.lenfield_name = elt.get('ref') + + else: + # Notreached + raise Exception("undefined tag '%s'" % elt.tag) + + def fixed_size(self): + return self.nmemb != None + + def resolve(self, module, parents): + if self.op == 'enumref': + self.lenfield_type = module.get_type(self.lenfield_name[0]) + self.lenfield_name = self.lenfield_name[1] + elif self.op == 'sumof': + # need to find the field with lenfield_name + for p in reversed(parents): + fields = dict([(f.field_name, f) for f in p.fields]) + if self.lenfield_name in fields.keys(): + if p.is_bitcase: + # switch is the anchestor + self.lenfield_parent = p.parents[-1] + else: + self.lenfield_parent = p + self.lenfield_type = fields[self.lenfield_name].field_type + break + diff --git a/libxcb/xcb-proto/xcbgen/xtypes.py b/libxcb/xcb-proto/xcbgen/xtypes.py index c78915846..f6d463445 100644 --- a/libxcb/xcb-proto/xcbgen/xtypes.py +++ b/libxcb/xcb-proto/xcbgen/xtypes.py @@ -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): @@ -123,7 +123,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'), '')) @@ -170,7 +174,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. @@ -189,10 +193,10 @@ 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: @@ -278,6 +282,7 @@ class ComplexType(Type): if self.resolved: return pads = 0 + enum = None # Resolve all of our field datatypes. for child in list(self.elt): @@ -289,6 +294,7 @@ class ComplexType(Type): 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 @@ -323,7 +329,7 @@ class ComplexType(Type): # 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) @@ -413,7 +419,7 @@ class SwitchType(ComplexType): 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): + 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. @@ -432,10 +438,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): @@ -483,7 +489,7 @@ class BitcaseType(ComplexType): 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 @@ -491,7 +497,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): @@ -518,6 +524,11 @@ 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: @@ -541,11 +552,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: @@ -581,6 +595,11 @@ class Event(ComplexType): tmp = elt.get('no-sequence-number') self.has_seq = (tmp == None or tmp.lower() == 'false' or tmp == '0') + + 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 @@ -629,4 +648,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) |