diff options
Diffstat (limited to 'libxcb/xcb-proto/xcbgen')
-rw-r--r-- | libxcb/xcb-proto/xcbgen/matcher.py | 226 | ||||
-rw-r--r-- | libxcb/xcb-proto/xcbgen/state.py | 332 | ||||
-rw-r--r-- | libxcb/xcb-proto/xcbgen/xtypes.py | 1264 |
3 files changed, 911 insertions, 911 deletions
diff --git a/libxcb/xcb-proto/xcbgen/matcher.py b/libxcb/xcb-proto/xcbgen/matcher.py index 6e45b236c..c4d99fc57 100644 --- a/libxcb/xcb-proto/xcbgen/matcher.py +++ b/libxcb/xcb-proto/xcbgen/matcher.py @@ -1,113 +1,113 @@ -''' -XML parser. One function for each top-level element in the schema. - -Most functions just declare a new object and add it to the module. -For typedefs, eventcopies, xidtypes, and other aliases though, -we do not create a new type object, we just record the existing one under a new name. -''' - -from os.path import join -from xml.etree.cElementTree import parse - -from xcbgen.xtypes import * - -def import_(node, module, namespace): - ''' - For imports, we load the file, create a new namespace object, - execute recursively, then record the import (for header files, etc.) - ''' - # To avoid circular import error - from xcbgen import state - new_file = join(namespace.dir, '%s.xml' % node.text) - new_root = parse(new_file).getroot() - new_namespace = state.Namespace(new_file) - execute(module, new_namespace) - if not module.has_import(node.text): - module.add_import(node.text, new_namespace) - -def typedef(node, module, namespace): - id = node.get('newname') - name = namespace.prefix + (id,) - type = module.get_type(node.get('oldname')) - module.add_type(id, namespace.ns, name, type) - -def xidtype(node, module, namespace): - id = node.get('name') - name = namespace.prefix + (id,) - type = module.get_type('CARD32') - module.add_type(id, namespace.ns, name, type) - -def xidunion(node, module, namespace): - id = node.get('name') - name = namespace.prefix + (id,) - type = module.get_type('CARD32') - module.add_type(id, namespace.ns, name, type) - -def enum(node, module, namespace): - id = node.get('name') - name = namespace.prefix + (id,) - type = Enum(name, node) - module.add_type(id, namespace.ns, name, type) - -def struct(node, module, namespace): - id = node.get('name') - name = namespace.prefix + (id,) - type = Struct(name, node) - module.add_type(id, namespace.ns, name, type) - -def union(node, module, namespace): - id = node.get('name') - name = namespace.prefix + (id,) - type = Union(name, node) - module.add_type(id, namespace.ns, name, type) - -def request(node, module, namespace): - id = node.get('name') - name = namespace.prefix + (id,) - type = Request(name, node) - module.add_request(id, name, type) - -def event(node, module, namespace): - id = node.get('name') - name = namespace.prefix + (id,) - event = Event(name, node) - event.add_opcode(node.get('number'), name, True) - module.add_event(id, name, event) - -def eventcopy(node, module, namespace): - id = node.get('name') - name = namespace.prefix + (id,) - event = module.get_event(node.get('ref')) - event.add_opcode(node.get('number'), name, False) - module.add_event(id, name, event) - -def error(node, module, namespace): - id = node.get('name') - name = namespace.prefix + (id,) - error = Error(name, node) - error.add_opcode(node.get('number'), name, True) - module.add_error(id, name, error) - -def errorcopy(node, module, namespace): - id = node.get('name') - name = namespace.prefix + (id,) - error = module.get_error(node.get('ref')) - error.add_opcode(node.get('number'), name, False) - module.add_error(id, name, error) - -funcs = {'import' : import_, - 'typedef' : typedef, - 'xidtype' : xidtype, - 'xidunion' : xidunion, - 'enum' : enum, - 'struct' : struct, - 'union' : union, - 'request' : request, - 'event' : event, - 'eventcopy' : eventcopy, - 'error' : error, - 'errorcopy' : errorcopy} - -def execute(module, namespace): - for elt in list(namespace.root): - funcs[elt.tag](elt, module, namespace) +'''
+XML parser. One function for each top-level element in the schema.
+
+Most functions just declare a new object and add it to the module.
+For typedefs, eventcopies, xidtypes, and other aliases though,
+we do not create a new type object, we just record the existing one under a new name.
+'''
+
+from os.path import join
+from xml.etree.cElementTree import parse
+
+from xcbgen.xtypes import *
+
+def import_(node, module, namespace):
+ '''
+ For imports, we load the file, create a new namespace object,
+ execute recursively, then record the import (for header files, etc.)
+ '''
+ # To avoid circular import error
+ from xcbgen import state
+ new_file = join(namespace.dir, '%s.xml' % node.text)
+ new_root = parse(new_file).getroot()
+ new_namespace = state.Namespace(new_file)
+ execute(module, new_namespace)
+ if not module.has_import(node.text):
+ module.add_import(node.text, new_namespace)
+
+def typedef(node, module, namespace):
+ id = node.get('newname')
+ name = namespace.prefix + (id,)
+ type = module.get_type(node.get('oldname'))
+ module.add_type(id, namespace.ns, name, type)
+
+def xidtype(node, module, namespace):
+ id = node.get('name')
+ name = namespace.prefix + (id,)
+ type = module.get_type('CARD32')
+ module.add_type(id, namespace.ns, name, type)
+
+def xidunion(node, module, namespace):
+ id = node.get('name')
+ name = namespace.prefix + (id,)
+ type = module.get_type('CARD32')
+ module.add_type(id, namespace.ns, name, type)
+
+def enum(node, module, namespace):
+ id = node.get('name')
+ name = namespace.prefix + (id,)
+ type = Enum(name, node)
+ module.add_type(id, namespace.ns, name, type)
+
+def struct(node, module, namespace):
+ id = node.get('name')
+ name = namespace.prefix + (id,)
+ type = Struct(name, node)
+ module.add_type(id, namespace.ns, name, type)
+
+def union(node, module, namespace):
+ id = node.get('name')
+ name = namespace.prefix + (id,)
+ type = Union(name, node)
+ module.add_type(id, namespace.ns, name, type)
+
+def request(node, module, namespace):
+ id = node.get('name')
+ name = namespace.prefix + (id,)
+ type = Request(name, node)
+ module.add_request(id, name, type)
+
+def event(node, module, namespace):
+ id = node.get('name')
+ name = namespace.prefix + (id,)
+ event = Event(name, node)
+ event.add_opcode(node.get('number'), name, True)
+ module.add_event(id, name, event)
+
+def eventcopy(node, module, namespace):
+ id = node.get('name')
+ name = namespace.prefix + (id,)
+ event = module.get_event(node.get('ref'))
+ event.add_opcode(node.get('number'), name, False)
+ module.add_event(id, name, event)
+
+def error(node, module, namespace):
+ id = node.get('name')
+ name = namespace.prefix + (id,)
+ error = Error(name, node)
+ error.add_opcode(node.get('number'), name, True)
+ module.add_error(id, name, error)
+
+def errorcopy(node, module, namespace):
+ id = node.get('name')
+ name = namespace.prefix + (id,)
+ error = module.get_error(node.get('ref'))
+ error.add_opcode(node.get('number'), name, False)
+ module.add_error(id, name, error)
+
+funcs = {'import' : import_,
+ 'typedef' : typedef,
+ 'xidtype' : xidtype,
+ 'xidunion' : xidunion,
+ 'enum' : enum,
+ 'struct' : struct,
+ 'union' : union,
+ 'request' : request,
+ 'event' : event,
+ 'eventcopy' : eventcopy,
+ 'error' : error,
+ 'errorcopy' : errorcopy}
+
+def execute(module, namespace):
+ for elt in list(namespace.root):
+ funcs[elt.tag](elt, module, namespace)
diff --git a/libxcb/xcb-proto/xcbgen/state.py b/libxcb/xcb-proto/xcbgen/state.py index ae3d2d45f..902a86341 100644 --- a/libxcb/xcb-proto/xcbgen/state.py +++ b/libxcb/xcb-proto/xcbgen/state.py @@ -1,166 +1,166 @@ -''' -This module contains the namespace class and the singleton module class. -''' -from os.path import dirname, basename -from xml.etree.cElementTree import parse - -from xcbgen import matcher -from xcbgen.error import * -from xcbgen.xtypes import * - -import __main__ - -class Namespace(object): - ''' - Contains the naming information for an extension. - - Public fields: - - header is the header attribute ("header file" name). - is_ext is true for extensions, false for xproto. - major_version and minor_version are extension version info. - ext_xname is the X extension name string. - ext_name is the XCB extension name prefix. - ''' - def __init__(self, filename): - # Path info - self.path = filename - self.dir = dirname(filename) - self.file = basename(filename) - - # Parse XML - self.root = parse(filename).getroot() - self.header = self.root.get('header') - self.ns = self.header + ':' - - # Get root element attributes - if self.root.get('extension-xname', False): - self.is_ext = True - self.major_version = self.root.get('major-version') - self.minor_version = self.root.get('minor-version') - self.ext_xname = self.root.get('extension-xname') - self.ext_name = self.root.get('extension-name') - self.prefix = ('xcb', self.ext_name) - else: - self.is_ext = False - self.ext_name = '' - self.prefix = ('xcb',) - - -class Module(object): - ''' - This is the grand, encompassing class that represents an entire XCB specification. - Only gets instantiated once, in the main() routine. - - Don't need to worry about this much except to declare it and to get the namespace. - - Public fields: - namespace contains the namespace info for the spec. - ''' - open = __main__.output['open'] - close = __main__.output['close'] - - def __init__(self, filename, output): - self.namespace = Namespace(filename) - self.output = output - - self.imports = [] - self.types = {} - self.events = {} - self.errors = {} - self.all = [] - - # Register some common types - self.add_type('CARD8', '', ('uint8_t',), tcard8) - self.add_type('CARD16', '', ('uint16_t',), tcard16) - self.add_type('CARD32', '', ('uint32_t',), tcard32) - self.add_type('INT8', '', ('int8_t',), tint8) - self.add_type('INT16', '', ('int16_t',), tint16) - self.add_type('INT32', '', ('int32_t',), tint32) - self.add_type('BYTE', '', ('uint8_t',), tcard8) - self.add_type('BOOL', '', ('uint8_t',), tcard8) - self.add_type('char', '', ('char',), tchar) - self.add_type('float', '', ('float',), tfloat) - self.add_type('double', '', ('double',), tdouble) - self.add_type('void', '', ('void',), tcard8) - - # This goes out and parses the rest of the XML - def register(self): - matcher.execute(self, self.namespace) - - # Recursively resolve all types - def resolve(self): - for (name, item) in self.all: - item.resolve(self) - - # Call all the output methods - def generate(self): - self.open() - - for (name, item) in self.all: - item.out(name) - - self.close() - - # Keeps track of what's been imported so far. - def add_import(self, name, namespace): - self.imports.append((name, namespace.header)) - - def has_import(self, name): - for (name_, header) in self.imports: - if name_ == name: - return True - return False - - # Keeps track of non-request/event/error datatypes - def add_type(self, id, ns, name, item): - key = ns + id - if key in self.types: - return - self.types[key] = (name, item) - if name[:-1] == self.namespace.prefix: - self.all.append((name, item)) - - def get_type_impl(self, id, idx): - key = id - if key in self.types: - return self.types[key][idx] - - key = self.namespace.ns + id - if key in self.types: - return self.types[key][idx] - - for key in self.types.keys(): - if key.rpartition(':')[2] == id: - return self.types[key][idx] - - raise ResolveException('Type %s not found' % id) - - def get_type(self, id): - return self.get_type_impl(id, 1) - - def get_type_name(self, id): - return self.get_type_impl(id, 0) - - # Keeps track of request datatypes - def add_request(self, id, name, item): - if name[:-1] == self.namespace.prefix: - self.all.append((name, item)) - - # Keeps track of event datatypes - def add_event(self, id, name, item): - self.events[id] = (name, item) - if name[:-1] == self.namespace.prefix: - self.all.append((name, item)) - - def get_event(self, id): - return self.events[id][1] - - # Keeps track of error datatypes - def add_error(self, id, name, item): - self.errors[id] = (name, item) - if name[:-1] == self.namespace.prefix: - self.all.append((name, item)) - - def get_error(self, id): - return self.errors[id][1] +'''
+This module contains the namespace class and the singleton module class.
+'''
+from os.path import dirname, basename
+from xml.etree.cElementTree import parse
+
+from xcbgen import matcher
+from xcbgen.error import *
+from xcbgen.xtypes import *
+
+import __main__
+
+class Namespace(object):
+ '''
+ Contains the naming information for an extension.
+
+ Public fields:
+
+ header is the header attribute ("header file" name).
+ is_ext is true for extensions, false for xproto.
+ major_version and minor_version are extension version info.
+ ext_xname is the X extension name string.
+ ext_name is the XCB extension name prefix.
+ '''
+ def __init__(self, filename):
+ # Path info
+ self.path = filename
+ self.dir = dirname(filename)
+ self.file = basename(filename)
+
+ # Parse XML
+ self.root = parse(filename).getroot()
+ self.header = self.root.get('header')
+ self.ns = self.header + ':'
+
+ # Get root element attributes
+ if self.root.get('extension-xname', False):
+ self.is_ext = True
+ self.major_version = self.root.get('major-version')
+ self.minor_version = self.root.get('minor-version')
+ self.ext_xname = self.root.get('extension-xname')
+ self.ext_name = self.root.get('extension-name')
+ self.prefix = ('xcb', self.ext_name)
+ else:
+ self.is_ext = False
+ self.ext_name = ''
+ self.prefix = ('xcb',)
+
+
+class Module(object):
+ '''
+ This is the grand, encompassing class that represents an entire XCB specification.
+ Only gets instantiated once, in the main() routine.
+
+ Don't need to worry about this much except to declare it and to get the namespace.
+
+ Public fields:
+ namespace contains the namespace info for the spec.
+ '''
+ open = __main__.output['open']
+ close = __main__.output['close']
+
+ def __init__(self, filename, output):
+ self.namespace = Namespace(filename)
+ self.output = output
+
+ self.imports = []
+ self.types = {}
+ self.events = {}
+ self.errors = {}
+ self.all = []
+
+ # Register some common types
+ self.add_type('CARD8', '', ('uint8_t',), tcard8)
+ self.add_type('CARD16', '', ('uint16_t',), tcard16)
+ self.add_type('CARD32', '', ('uint32_t',), tcard32)
+ self.add_type('INT8', '', ('int8_t',), tint8)
+ self.add_type('INT16', '', ('int16_t',), tint16)
+ self.add_type('INT32', '', ('int32_t',), tint32)
+ self.add_type('BYTE', '', ('uint8_t',), tcard8)
+ self.add_type('BOOL', '', ('uint8_t',), tcard8)
+ self.add_type('char', '', ('char',), tchar)
+ self.add_type('float', '', ('float',), tfloat)
+ self.add_type('double', '', ('double',), tdouble)
+ self.add_type('void', '', ('void',), tcard8)
+
+ # This goes out and parses the rest of the XML
+ def register(self):
+ matcher.execute(self, self.namespace)
+
+ # Recursively resolve all types
+ def resolve(self):
+ for (name, item) in self.all:
+ item.resolve(self)
+
+ # Call all the output methods
+ def generate(self):
+ self.open()
+
+ for (name, item) in self.all:
+ item.out(name)
+
+ self.close()
+
+ # Keeps track of what's been imported so far.
+ def add_import(self, name, namespace):
+ self.imports.append((name, namespace.header))
+
+ def has_import(self, name):
+ for (name_, header) in self.imports:
+ if name_ == name:
+ return True
+ return False
+
+ # Keeps track of non-request/event/error datatypes
+ def add_type(self, id, ns, name, item):
+ key = ns + id
+ if key in self.types:
+ return
+ self.types[key] = (name, item)
+ if name[:-1] == self.namespace.prefix:
+ self.all.append((name, item))
+
+ def get_type_impl(self, id, idx):
+ key = id
+ if key in self.types:
+ return self.types[key][idx]
+
+ key = self.namespace.ns + id
+ if key in self.types:
+ return self.types[key][idx]
+
+ for key in self.types.keys():
+ if key.rpartition(':')[2] == id:
+ return self.types[key][idx]
+
+ raise ResolveException('Type %s not found' % id)
+
+ def get_type(self, id):
+ return self.get_type_impl(id, 1)
+
+ def get_type_name(self, id):
+ return self.get_type_impl(id, 0)
+
+ # Keeps track of request datatypes
+ def add_request(self, id, name, item):
+ if name[:-1] == self.namespace.prefix:
+ self.all.append((name, item))
+
+ # Keeps track of event datatypes
+ def add_event(self, id, name, item):
+ self.events[id] = (name, item)
+ if name[:-1] == self.namespace.prefix:
+ self.all.append((name, item))
+
+ def get_event(self, id):
+ return self.events[id][1]
+
+ # Keeps track of error datatypes
+ def add_error(self, id, name, item):
+ self.errors[id] = (name, item)
+ if name[:-1] == self.namespace.prefix:
+ self.all.append((name, item))
+
+ def get_error(self, id):
+ return self.errors[id][1]
diff --git a/libxcb/xcb-proto/xcbgen/xtypes.py b/libxcb/xcb-proto/xcbgen/xtypes.py index 14c318ac3..882acc9b8 100644 --- a/libxcb/xcb-proto/xcbgen/xtypes.py +++ b/libxcb/xcb-proto/xcbgen/xtypes.py @@ -1,632 +1,632 @@ -''' -This module contains the classes which represent XCB data types. -''' -from xcbgen.expr import Field, Expression -import __main__ - -class Type(object): - ''' - Abstract base class for all XCB data types. - Contains default fields, and some abstract methods. - ''' - def __init__(self, name): - ''' - Default structure initializer. Sets up default fields. - - Public fields: - name is a tuple of strings specifying the full type name. - size is the size of the datatype in bytes, or None if variable-sized. - 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 - - # Screw isinstance(). - self.is_simple = False - self.is_list = False - self.is_expr = False - self.is_container = False - self.is_reply = False - self.is_union = False - self.is_pad = False - self.is_switch = False - self.is_bitcase = False - - def resolve(self, module): - ''' - Abstract method for resolving a type. - This should make sure any referenced types are already declared. - ''' - raise Exception('abstract resolve method not overridden!') - - def out(self, name): - ''' - Abstract method for outputting code. - These are declared in the language-specific modules, and - there must be a dictionary containing them declared when this module is imported! - ''' - raise Exception('abstract out method not overridden!') - - def fixed_size(self): - ''' - Abstract method for determining if the data type is fixed-size. - ''' - raise Exception('abstract fixed_size method not overridden!') - - def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto): - ''' - 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. - - module is the global module 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) - - # 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_field - return - - complex_type.fields.append(new_field) - - -class SimpleType(Type): - ''' - Derived class which represents a cardinal type like CARD32 or char. - Any type which is typedef'ed to cardinal will be one of these. - - Public fields added: - none - ''' - def __init__(self, name, size): - Type.__init__(self, name) - self.is_simple = True - self.size = size - self.nmemb = 1 - - def resolve(self, module): - self.resolved = True - - def fixed_size(self): - return True - - out = __main__.output['simple'] - - -# Cardinal datatype globals. See module __init__ method. -tcard8 = SimpleType(('uint8_t',), 1) -tcard16 = SimpleType(('uint16_t',), 2) -tcard32 = SimpleType(('uint32_t',), 4) -tint8 = SimpleType(('int8_t',), 1) -tint16 = SimpleType(('int16_t',), 2) -tint32 = SimpleType(('int32_t',), 4) -tchar = SimpleType(('char',), 1) -tfloat = SimpleType(('float',), 4) -tdouble = SimpleType(('double',), 8) - - -class Enum(SimpleType): - ''' - Derived class which represents an enum. Fixed-size. - - Public fields added: - values contains a list of (name, value) tuples. value is empty, or a number. - bits contains a list of (name, bitnum) tuples. items only appear if specified as a bit. bitnum is a number. - ''' - def __init__(self, name, elt): - SimpleType.__init__(self, name, 4) - self.values = [] - self.bits = [] - for item in list(elt): - # First check if we're using a default value - if len(list(item)) == 0: - self.values.append((item.get('name'), '')) - continue - - # An explicit value or bit was specified. - value = list(item)[0] - if value.tag == 'value': - self.values.append((item.get('name'), value.text)) - elif value.tag == 'bit': - self.values.append((item.get('name'), '%u' % (1 << int(value.text, 0)))) - self.bits.append((item.get('name'), value.text)) - - def resolve(self, module): - self.resolved = True - - def fixed_size(self): - return True - - out = __main__.output['enum'] - - -class ListType(Type): - ''' - Derived class which represents a list of some other datatype. Fixed- or variable-sized. - - Public fields added: - member is the datatype of the list elements. - parent is the structure type containing the list. - expr is an Expression object containing the length information, for variable-sized lists. - ''' - def __init__(self, elt, member, *parent): - Type.__init__(self, member.name) - self.is_list = True - self.member = member - self.parents = list(parent) - - if elt.tag == 'list': - elts = list(elt) - self.expr = Expression(elts[0] if len(elts) else elt, self) - elif elt.tag == 'valueparam': - self.expr = Expression(elt, self) - - 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): - 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. - lenfid = self.expr.lenfield_type - lenfield_name = self.expr.lenfield_name - lenwire = self.expr.lenwire - needlen = True - - # See if the length field is already in the structure. - for parent in self.parents: - for field in parent.fields: - if field.field_name == lenfield_name: - needlen = False - - # It isn't, so we need to add it to the structure ourself. - 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) - - # 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) - - def resolve(self, module): - if self.resolved: - return - self.member.resolve(module) - 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.parents: - for field in parent.fields: - if field.field_name == self.expr.lenfield_name and field.wire: - self.expr.lenfield = field - break - - self.resolved = True - - def fixed_size(self): - return self.member.fixed_size() and self.expr.fixed_size() - -class ExprType(Type): - ''' - Derived class which represents an exprfield. Fixed size. - - Public fields added: - expr is an Expression object containing the value of the field. - ''' - def __init__(self, elt, member, *parent): - Type.__init__(self, member.name) - self.is_expr = True - self.member = member - self.parent = parent - - self.expr = Expression(list(elt)[0], self) - - self.size = member.size - self.nmemb = 1 - - def resolve(self, module): - if self.resolved: - return - self.member.resolve(module) - self.resolved = True - - def fixed_size(self): - return True - -class PadType(Type): - ''' - Derived class which represents a padding field. - ''' - def __init__(self, elt): - Type.__init__(self, tcard8.name) - self.is_pad = True - self.size = 1 - self.nmemb = 1 if (elt == None) else int(elt.get('bytes'), 0) - - def resolve(self, module): - self.resolved = True - - def fixed_size(self): - return True - - -class ComplexType(Type): - ''' - Derived class which represents a structure. Base type for all structure types. - - Public fields added: - fields is an array of Field objects describing the structure fields. - ''' - def __init__(self, name, elt): - Type.__init__(self, name) - self.is_container = True - self.elt = elt - self.fields = [] - self.nmemb = 1 - self.size = 0 - self.lenfield_parent = [self] - - def resolve(self, module): - if self.resolved: - return - pads = 0 - - # Resolve all of our field datatypes. - for child in list(self.elt): - if child.tag == 'pad': - field_name = 'pad' + str(pads) - fkey = 'CARD8' - type = PadType(child) - pads = pads + 1 - visible = False - elif child.tag == 'field': - field_name = child.get('name') - fkey = child.get('type') - type = module.get_type(fkey) - visible = True - elif child.tag == 'exprfield': - field_name = child.get('name') - fkey = child.get('type') - type = ExprType(child, module.get_type(fkey), *self.lenfield_parent) - visible = False - elif child.tag == 'list': - field_name = child.get('name') - fkey = child.get('type') - type = ListType(child, module.get_type(fkey), *self.lenfield_parent) - visible = True - elif child.tag == 'valueparam': - field_name = child.get('value-list-name') - fkey = 'CARD32' - type = ListType(child, module.get_type(fkey), *self.lenfield_parent) - visible = True - elif child.tag == 'switch': - field_name = child.get('name') - # construct the switch type name from the parent type and the field name - field_type = self.name + (field_name,) - type = SwitchType(field_type, child, *self.lenfield_parent) - visible = True - type.make_member_of(module, self, field_type, field_name, visible, True, False) - type.resolve(module) - continue - else: - # Hit this on Reply - 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) - # Recursively resolve the type (could be another structure, list) - type.resolve(module) - - self.calc_size() # Figure out how big we are - self.resolved = True - - def calc_size(self): - self.size = 0 - for m in self.fields: - if not m.wire: - continue - if m.type.fixed_size(): - self.size = self.size + (m.type.size * m.type.nmemb) - else: - self.size = None - break - - def fixed_size(self): - for m in self.fields: - if not m.type.fixed_size(): - return False - return True - -class SwitchType(ComplexType): - ''' - Derived class which represents a List of Items. - - Public fields added: - bitcases is an array of Bitcase objects describing the list items - ''' - - def __init__(self, name, elt, *parents): - ComplexType.__init__(self, name, elt) - 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, - # 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) - - def resolve(self, module): - if self.resolved: - return -# pads = 0 - - parents = list(self.parents) + [self] - - # Resolve all of our field datatypes. - for index, child in enumerate(list(self.elt)): - if child.tag == 'bitcase': - field_name = child.get('name') - if field_name is None: - field_type = self.name + ('bitcase%d' % index,) - else: - field_type = self.name + (field_name,) - - # use self.parent to indicate anchestor, - # as switch does not contain named fields itself - type = BitcaseType(index, field_type, child, *parents) - # construct the switch type name from the parent type and the field name - if field_name is None: - type.has_name = False - # Get the full type name for the field - field_type = type.name - visible = True - - # add the field to ourself - type.make_member_of(module, self, field_type, field_name, visible, True, False) - - # recursively resolve the type (could be another structure, list) - type.resolve(module) - inserted = False - for new_field in type.fields: - # We dump the _placeholder_byte if any fields are added. - for (idx, field) in enumerate(self.fields): - if field == _placeholder_byte: - self.fields[idx] = new_field - inserted = True - break - if False == inserted: - self.fields.append(new_field) - - 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): - 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. - lenfid = self.expr.lenfield_type - lenfield_name = self.expr.lenfield_name - lenwire = self.expr.lenwire - needlen = True - - # See if the length field is already in the structure. - for parent in self.parents: - for field in parent.fields: - if field.field_name == lenfield_name: - needlen = False - - # It isn't, so we need to add it to the structure ourself. - 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) - - # 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) - - # size for switch can only be calculated at runtime - def calc_size(self): - pass - - # note: switch is _always_ of variable size, but we indicate here wether - # it contains elements that are variable-sized themselves - def fixed_size(self): - return False -# for m in self.fields: -# if not m.type.fixed_size(): -# return False -# return True - - -class Struct(ComplexType): - ''' - Derived class representing a struct data type. - ''' - out = __main__.output['struct'] - - -class Union(ComplexType): - ''' - Derived class representing a union data type. - ''' - def __init__(self, name, elt): - ComplexType.__init__(self, name, elt) - self.is_union = True - - out = __main__.output['union'] - - -class BitcaseType(ComplexType): - ''' - Derived class representing a struct data type. - ''' - 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.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): - ''' - 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. - ''' - new_field = Field(self, field_type, field_name, visible, wire, auto) - - # We dump the _placeholder_byte if any bitcases are added. - for (idx, field) in enumerate(switch_type.bitcases): - if field == _placeholder_byte: - switch_type.bitcases[idx] = new_field - return - - switch_type.bitcases.append(new_field) - - def resolve(self, module): - if self.resolved: - return - - self.expr.resolve(module, self.parents+[self]) - - # Resolve the bitcase expression - ComplexType.resolve(self, module) - - -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 - - def resolve(self, module): - if self.resolved: - return - # Add the automatic protocol fields - self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True)) - self.fields.append(_placeholder_byte) - self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True)) - self.fields.append(Field(tcard32, tcard32.name, 'length', False, True, True)) - ComplexType.resolve(self, module) - - -class Request(ComplexType): - ''' - Derived class representing a request. - - Public fields added: - reply contains the reply datatype or None for void requests. - opcode contains the request number. - ''' - def __init__(self, name, elt): - ComplexType.__init__(self, name, elt) - self.reply = None - self.opcode = elt.get('opcode') - - for child in list(elt): - if child.tag == 'reply': - self.reply = Reply(name, child) - - def resolve(self, module): - if self.resolved: - return - # Add the automatic protocol fields - if module.namespace.is_ext: - self.fields.append(Field(tcard8, tcard8.name, 'major_opcode', False, True, True)) - self.fields.append(Field(tcard8, tcard8.name, 'minor_opcode', False, True, True)) - self.fields.append(Field(tcard16, tcard16.name, 'length', False, True, True)) - ComplexType.resolve(self, module) - else: - self.fields.append(Field(tcard8, tcard8.name, 'major_opcode', False, True, True)) - self.fields.append(_placeholder_byte) - self.fields.append(Field(tcard16, tcard16.name, 'length', False, True, True)) - ComplexType.resolve(self, module) - - if self.reply: - self.reply.resolve(module) - - out = __main__.output['request'] - - -class Event(ComplexType): - ''' - Derived class representing an event data type. - - Public fields added: - opcodes is a dictionary of name -> opcode number, for eventcopies. - ''' - def __init__(self, name, elt): - 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') - - def add_opcode(self, opcode, name, main): - self.opcodes[name] = opcode - if main: - self.name = name - - def resolve(self, module): - 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)) - ComplexType.resolve(self, module) - - out = __main__.output['event'] - - -class Error(ComplexType): - ''' - Derived class representing an error data type. - - 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 = {} - - def add_opcode(self, opcode, name, main): - self.opcodes[name] = opcode - if main: - self.name = name - - def resolve(self, module): - if self.resolved: - return - - # Add the automatic protocol fields - self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True)) - self.fields.append(Field(tcard8, tcard8.name, 'error_code', False, True, True)) - self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True)) - ComplexType.resolve(self, module) - - out = __main__.output['error'] - -_placeholder_byte = Field(PadType(None), tcard8.name, 'pad0', False, True, False) +'''
+This module contains the classes which represent XCB data types.
+'''
+from xcbgen.expr import Field, Expression
+import __main__
+
+class Type(object):
+ '''
+ Abstract base class for all XCB data types.
+ Contains default fields, and some abstract methods.
+ '''
+ def __init__(self, name):
+ '''
+ Default structure initializer. Sets up default fields.
+
+ Public fields:
+ name is a tuple of strings specifying the full type name.
+ size is the size of the datatype in bytes, or None if variable-sized.
+ 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
+
+ # Screw isinstance().
+ self.is_simple = False
+ self.is_list = False
+ self.is_expr = False
+ self.is_container = False
+ self.is_reply = False
+ self.is_union = False
+ self.is_pad = False
+ self.is_switch = False
+ self.is_bitcase = False
+
+ def resolve(self, module):
+ '''
+ Abstract method for resolving a type.
+ This should make sure any referenced types are already declared.
+ '''
+ raise Exception('abstract resolve method not overridden!')
+
+ def out(self, name):
+ '''
+ Abstract method for outputting code.
+ These are declared in the language-specific modules, and
+ there must be a dictionary containing them declared when this module is imported!
+ '''
+ raise Exception('abstract out method not overridden!')
+
+ def fixed_size(self):
+ '''
+ Abstract method for determining if the data type is fixed-size.
+ '''
+ raise Exception('abstract fixed_size method not overridden!')
+
+ def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto):
+ '''
+ 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.
+
+ module is the global module 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)
+
+ # 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_field
+ return
+
+ complex_type.fields.append(new_field)
+
+
+class SimpleType(Type):
+ '''
+ Derived class which represents a cardinal type like CARD32 or char.
+ Any type which is typedef'ed to cardinal will be one of these.
+
+ Public fields added:
+ none
+ '''
+ def __init__(self, name, size):
+ Type.__init__(self, name)
+ self.is_simple = True
+ self.size = size
+ self.nmemb = 1
+
+ def resolve(self, module):
+ self.resolved = True
+
+ def fixed_size(self):
+ return True
+
+ out = __main__.output['simple']
+
+
+# Cardinal datatype globals. See module __init__ method.
+tcard8 = SimpleType(('uint8_t',), 1)
+tcard16 = SimpleType(('uint16_t',), 2)
+tcard32 = SimpleType(('uint32_t',), 4)
+tint8 = SimpleType(('int8_t',), 1)
+tint16 = SimpleType(('int16_t',), 2)
+tint32 = SimpleType(('int32_t',), 4)
+tchar = SimpleType(('char',), 1)
+tfloat = SimpleType(('float',), 4)
+tdouble = SimpleType(('double',), 8)
+
+
+class Enum(SimpleType):
+ '''
+ Derived class which represents an enum. Fixed-size.
+
+ Public fields added:
+ values contains a list of (name, value) tuples. value is empty, or a number.
+ bits contains a list of (name, bitnum) tuples. items only appear if specified as a bit. bitnum is a number.
+ '''
+ def __init__(self, name, elt):
+ SimpleType.__init__(self, name, 4)
+ self.values = []
+ self.bits = []
+ for item in list(elt):
+ # First check if we're using a default value
+ if len(list(item)) == 0:
+ self.values.append((item.get('name'), ''))
+ continue
+
+ # An explicit value or bit was specified.
+ value = list(item)[0]
+ if value.tag == 'value':
+ self.values.append((item.get('name'), value.text))
+ elif value.tag == 'bit':
+ self.values.append((item.get('name'), '%u' % (1 << int(value.text, 0))))
+ self.bits.append((item.get('name'), value.text))
+
+ def resolve(self, module):
+ self.resolved = True
+
+ def fixed_size(self):
+ return True
+
+ out = __main__.output['enum']
+
+
+class ListType(Type):
+ '''
+ Derived class which represents a list of some other datatype. Fixed- or variable-sized.
+
+ Public fields added:
+ member is the datatype of the list elements.
+ parent is the structure type containing the list.
+ expr is an Expression object containing the length information, for variable-sized lists.
+ '''
+ def __init__(self, elt, member, *parent):
+ Type.__init__(self, member.name)
+ self.is_list = True
+ self.member = member
+ self.parents = list(parent)
+
+ if elt.tag == 'list':
+ elts = list(elt)
+ self.expr = Expression(elts[0] if len(elts) else elt, self)
+ elif elt.tag == 'valueparam':
+ self.expr = Expression(elt, self)
+
+ 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):
+ 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.
+ lenfid = self.expr.lenfield_type
+ lenfield_name = self.expr.lenfield_name
+ lenwire = self.expr.lenwire
+ needlen = True
+
+ # See if the length field is already in the structure.
+ for parent in self.parents:
+ for field in parent.fields:
+ if field.field_name == lenfield_name:
+ needlen = False
+
+ # It isn't, so we need to add it to the structure ourself.
+ 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)
+
+ # 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)
+
+ def resolve(self, module):
+ if self.resolved:
+ return
+ self.member.resolve(module)
+ 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.parents:
+ for field in parent.fields:
+ if field.field_name == self.expr.lenfield_name and field.wire:
+ self.expr.lenfield = field
+ break
+
+ self.resolved = True
+
+ def fixed_size(self):
+ return self.member.fixed_size() and self.expr.fixed_size()
+
+class ExprType(Type):
+ '''
+ Derived class which represents an exprfield. Fixed size.
+
+ Public fields added:
+ expr is an Expression object containing the value of the field.
+ '''
+ def __init__(self, elt, member, *parent):
+ Type.__init__(self, member.name)
+ self.is_expr = True
+ self.member = member
+ self.parent = parent
+
+ self.expr = Expression(list(elt)[0], self)
+
+ self.size = member.size
+ self.nmemb = 1
+
+ def resolve(self, module):
+ if self.resolved:
+ return
+ self.member.resolve(module)
+ self.resolved = True
+
+ def fixed_size(self):
+ return True
+
+class PadType(Type):
+ '''
+ Derived class which represents a padding field.
+ '''
+ def __init__(self, elt):
+ Type.__init__(self, tcard8.name)
+ self.is_pad = True
+ self.size = 1
+ self.nmemb = 1 if (elt == None) else int(elt.get('bytes'), 0)
+
+ def resolve(self, module):
+ self.resolved = True
+
+ def fixed_size(self):
+ return True
+
+
+class ComplexType(Type):
+ '''
+ Derived class which represents a structure. Base type for all structure types.
+
+ Public fields added:
+ fields is an array of Field objects describing the structure fields.
+ '''
+ def __init__(self, name, elt):
+ Type.__init__(self, name)
+ self.is_container = True
+ self.elt = elt
+ self.fields = []
+ self.nmemb = 1
+ self.size = 0
+ self.lenfield_parent = [self]
+
+ def resolve(self, module):
+ if self.resolved:
+ return
+ pads = 0
+
+ # Resolve all of our field datatypes.
+ for child in list(self.elt):
+ if child.tag == 'pad':
+ field_name = 'pad' + str(pads)
+ fkey = 'CARD8'
+ type = PadType(child)
+ pads = pads + 1
+ visible = False
+ elif child.tag == 'field':
+ field_name = child.get('name')
+ fkey = child.get('type')
+ type = module.get_type(fkey)
+ visible = True
+ elif child.tag == 'exprfield':
+ field_name = child.get('name')
+ fkey = child.get('type')
+ type = ExprType(child, module.get_type(fkey), *self.lenfield_parent)
+ visible = False
+ elif child.tag == 'list':
+ field_name = child.get('name')
+ fkey = child.get('type')
+ type = ListType(child, module.get_type(fkey), *self.lenfield_parent)
+ visible = True
+ elif child.tag == 'valueparam':
+ field_name = child.get('value-list-name')
+ fkey = 'CARD32'
+ type = ListType(child, module.get_type(fkey), *self.lenfield_parent)
+ visible = True
+ elif child.tag == 'switch':
+ field_name = child.get('name')
+ # construct the switch type name from the parent type and the field name
+ field_type = self.name + (field_name,)
+ type = SwitchType(field_type, child, *self.lenfield_parent)
+ visible = True
+ type.make_member_of(module, self, field_type, field_name, visible, True, False)
+ type.resolve(module)
+ continue
+ else:
+ # Hit this on Reply
+ 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)
+ # Recursively resolve the type (could be another structure, list)
+ type.resolve(module)
+
+ self.calc_size() # Figure out how big we are
+ self.resolved = True
+
+ def calc_size(self):
+ self.size = 0
+ for m in self.fields:
+ if not m.wire:
+ continue
+ if m.type.fixed_size():
+ self.size = self.size + (m.type.size * m.type.nmemb)
+ else:
+ self.size = None
+ break
+
+ def fixed_size(self):
+ for m in self.fields:
+ if not m.type.fixed_size():
+ return False
+ return True
+
+class SwitchType(ComplexType):
+ '''
+ Derived class which represents a List of Items.
+
+ Public fields added:
+ bitcases is an array of Bitcase objects describing the list items
+ '''
+
+ def __init__(self, name, elt, *parents):
+ ComplexType.__init__(self, name, elt)
+ 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,
+ # 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)
+
+ def resolve(self, module):
+ if self.resolved:
+ return
+# pads = 0
+
+ parents = list(self.parents) + [self]
+
+ # Resolve all of our field datatypes.
+ for index, child in enumerate(list(self.elt)):
+ if child.tag == 'bitcase':
+ field_name = child.get('name')
+ if field_name is None:
+ field_type = self.name + ('bitcase%d' % index,)
+ else:
+ field_type = self.name + (field_name,)
+
+ # use self.parent to indicate anchestor,
+ # as switch does not contain named fields itself
+ type = BitcaseType(index, field_type, child, *parents)
+ # construct the switch type name from the parent type and the field name
+ if field_name is None:
+ type.has_name = False
+ # Get the full type name for the field
+ field_type = type.name
+ visible = True
+
+ # add the field to ourself
+ type.make_member_of(module, self, field_type, field_name, visible, True, False)
+
+ # recursively resolve the type (could be another structure, list)
+ type.resolve(module)
+ inserted = False
+ for new_field in type.fields:
+ # We dump the _placeholder_byte if any fields are added.
+ for (idx, field) in enumerate(self.fields):
+ if field == _placeholder_byte:
+ self.fields[idx] = new_field
+ inserted = True
+ break
+ if False == inserted:
+ self.fields.append(new_field)
+
+ 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):
+ 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.
+ lenfid = self.expr.lenfield_type
+ lenfield_name = self.expr.lenfield_name
+ lenwire = self.expr.lenwire
+ needlen = True
+
+ # See if the length field is already in the structure.
+ for parent in self.parents:
+ for field in parent.fields:
+ if field.field_name == lenfield_name:
+ needlen = False
+
+ # It isn't, so we need to add it to the structure ourself.
+ 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)
+
+ # 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)
+
+ # size for switch can only be calculated at runtime
+ def calc_size(self):
+ pass
+
+ # note: switch is _always_ of variable size, but we indicate here wether
+ # it contains elements that are variable-sized themselves
+ def fixed_size(self):
+ return False
+# for m in self.fields:
+# if not m.type.fixed_size():
+# return False
+# return True
+
+
+class Struct(ComplexType):
+ '''
+ Derived class representing a struct data type.
+ '''
+ out = __main__.output['struct']
+
+
+class Union(ComplexType):
+ '''
+ Derived class representing a union data type.
+ '''
+ def __init__(self, name, elt):
+ ComplexType.__init__(self, name, elt)
+ self.is_union = True
+
+ out = __main__.output['union']
+
+
+class BitcaseType(ComplexType):
+ '''
+ Derived class representing a struct data type.
+ '''
+ 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.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):
+ '''
+ 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.
+ '''
+ new_field = Field(self, field_type, field_name, visible, wire, auto)
+
+ # We dump the _placeholder_byte if any bitcases are added.
+ for (idx, field) in enumerate(switch_type.bitcases):
+ if field == _placeholder_byte:
+ switch_type.bitcases[idx] = new_field
+ return
+
+ switch_type.bitcases.append(new_field)
+
+ def resolve(self, module):
+ if self.resolved:
+ return
+
+ self.expr.resolve(module, self.parents+[self])
+
+ # Resolve the bitcase expression
+ ComplexType.resolve(self, module)
+
+
+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
+
+ def resolve(self, module):
+ if self.resolved:
+ return
+ # Add the automatic protocol fields
+ self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))
+ self.fields.append(_placeholder_byte)
+ self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True))
+ self.fields.append(Field(tcard32, tcard32.name, 'length', False, True, True))
+ ComplexType.resolve(self, module)
+
+
+class Request(ComplexType):
+ '''
+ Derived class representing a request.
+
+ Public fields added:
+ reply contains the reply datatype or None for void requests.
+ opcode contains the request number.
+ '''
+ def __init__(self, name, elt):
+ ComplexType.__init__(self, name, elt)
+ self.reply = None
+ self.opcode = elt.get('opcode')
+
+ for child in list(elt):
+ if child.tag == 'reply':
+ self.reply = Reply(name, child)
+
+ def resolve(self, module):
+ if self.resolved:
+ return
+ # Add the automatic protocol fields
+ if module.namespace.is_ext:
+ self.fields.append(Field(tcard8, tcard8.name, 'major_opcode', False, True, True))
+ self.fields.append(Field(tcard8, tcard8.name, 'minor_opcode', False, True, True))
+ self.fields.append(Field(tcard16, tcard16.name, 'length', False, True, True))
+ ComplexType.resolve(self, module)
+ else:
+ self.fields.append(Field(tcard8, tcard8.name, 'major_opcode', False, True, True))
+ self.fields.append(_placeholder_byte)
+ self.fields.append(Field(tcard16, tcard16.name, 'length', False, True, True))
+ ComplexType.resolve(self, module)
+
+ if self.reply:
+ self.reply.resolve(module)
+
+ out = __main__.output['request']
+
+
+class Event(ComplexType):
+ '''
+ Derived class representing an event data type.
+
+ Public fields added:
+ opcodes is a dictionary of name -> opcode number, for eventcopies.
+ '''
+ def __init__(self, name, elt):
+ 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')
+
+ def add_opcode(self, opcode, name, main):
+ self.opcodes[name] = opcode
+ if main:
+ self.name = name
+
+ def resolve(self, module):
+ 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))
+ ComplexType.resolve(self, module)
+
+ out = __main__.output['event']
+
+
+class Error(ComplexType):
+ '''
+ Derived class representing an error data type.
+
+ 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 = {}
+
+ def add_opcode(self, opcode, name, main):
+ self.opcodes[name] = opcode
+ if main:
+ self.name = name
+
+ def resolve(self, module):
+ if self.resolved:
+ return
+
+ # Add the automatic protocol fields
+ self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))
+ self.fields.append(Field(tcard8, tcard8.name, 'error_code', False, True, True))
+ self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True))
+ ComplexType.resolve(self, module)
+
+ out = __main__.output['error']
+
+_placeholder_byte = Field(PadType(None), tcard8.name, 'pad0', False, True, False)
|