state.py revision f591e195
1d4401354Smrg''' 2d4401354SmrgThis module contains the namespace class and the singleton module class. 3d4401354Smrg''' 4d4401354Smrgfrom os.path import dirname, basename 5d4401354Smrgfrom xml.etree.cElementTree import parse 6d4401354Smrg 7986c8b3dSmrgfrom xcbgen import matcher 8986c8b3dSmrgfrom xcbgen.error import * 9986c8b3dSmrgfrom xcbgen.xtypes import * 10d4401354Smrg 11d4401354Smrgimport __main__ 12d4401354Smrg 13d4401354Smrgclass Namespace(object): 14d4401354Smrg ''' 15d4401354Smrg Contains the naming information for an extension. 16d4401354Smrg 17d4401354Smrg Public fields: 18d4401354Smrg 19d4401354Smrg header is the header attribute ("header file" name). 20d4401354Smrg is_ext is true for extensions, false for xproto. 21d4401354Smrg major_version and minor_version are extension version info. 22d4401354Smrg ext_xname is the X extension name string. 23d4401354Smrg ext_name is the XCB extension name prefix. 24d4401354Smrg ''' 25d4401354Smrg def __init__(self, filename): 26d4401354Smrg # Path info 27d4401354Smrg self.path = filename 28d4401354Smrg self.dir = dirname(filename) 29d4401354Smrg self.file = basename(filename) 30d4401354Smrg 31d4401354Smrg # Parse XML 32d4401354Smrg self.root = parse(filename).getroot() 33d4401354Smrg self.header = self.root.get('header') 34d4401354Smrg self.ns = self.header + ':' 35d4401354Smrg 36d4401354Smrg # Get root element attributes 37d4401354Smrg if self.root.get('extension-xname', False): 38d4401354Smrg self.is_ext = True 39d4401354Smrg self.major_version = self.root.get('major-version') 40d4401354Smrg self.minor_version = self.root.get('minor-version') 41d4401354Smrg self.ext_xname = self.root.get('extension-xname') 42d4401354Smrg self.ext_name = self.root.get('extension-name') 43d4401354Smrg self.prefix = ('xcb', self.ext_name) 44d4401354Smrg else: 45d4401354Smrg self.is_ext = False 46d4401354Smrg self.ext_name = '' 47d4401354Smrg self.prefix = ('xcb',) 48d4401354Smrg 49d4401354Smrg 50d4401354Smrgclass Module(object): 51d4401354Smrg ''' 52d4401354Smrg This is the grand, encompassing class that represents an entire XCB specification. 53d4401354Smrg Only gets instantiated once, in the main() routine. 54d4401354Smrg 55d4401354Smrg Don't need to worry about this much except to declare it and to get the namespace. 56d4401354Smrg 57d4401354Smrg Public fields: 58d4401354Smrg namespace contains the namespace info for the spec. 59d4401354Smrg ''' 60d4401354Smrg open = __main__.output['open'] 61d4401354Smrg close = __main__.output['close'] 62d4401354Smrg 63d4401354Smrg def __init__(self, filename, output): 64d4401354Smrg self.namespace = Namespace(filename) 65d4401354Smrg self.output = output 66d4401354Smrg 67d4401354Smrg self.imports = [] 68d4401354Smrg self.types = {} 69d4401354Smrg self.events = {} 70d4401354Smrg self.errors = {} 71d4401354Smrg self.all = [] 72d4401354Smrg 73d4401354Smrg # Register some common types 74d4401354Smrg self.add_type('CARD8', '', ('uint8_t',), tcard8) 75d4401354Smrg self.add_type('CARD16', '', ('uint16_t',), tcard16) 76d4401354Smrg self.add_type('CARD32', '', ('uint32_t',), tcard32) 77f591e195Smrg self.add_type('CARD64', '', ('uint64_t',), tcard64) 78d4401354Smrg self.add_type('INT8', '', ('int8_t',), tint8) 79d4401354Smrg self.add_type('INT16', '', ('int16_t',), tint16) 80d4401354Smrg self.add_type('INT32', '', ('int32_t',), tint32) 81f591e195Smrg self.add_type('INT64', '', ('int64_t',), tint64) 82d4401354Smrg self.add_type('BYTE', '', ('uint8_t',), tcard8) 83d4401354Smrg self.add_type('BOOL', '', ('uint8_t',), tcard8) 84d4401354Smrg self.add_type('char', '', ('char',), tchar) 85d4401354Smrg self.add_type('float', '', ('float',), tfloat) 86d4401354Smrg self.add_type('double', '', ('double',), tdouble) 87d4401354Smrg self.add_type('void', '', ('void',), tcard8) 88d4401354Smrg 89d4401354Smrg # This goes out and parses the rest of the XML 90d4401354Smrg def register(self): 91d4401354Smrg matcher.execute(self, self.namespace) 92d4401354Smrg 93d4401354Smrg # Recursively resolve all types 94d4401354Smrg def resolve(self): 95d4401354Smrg for (name, item) in self.all: 96d4401354Smrg item.resolve(self) 97d4401354Smrg 98d4401354Smrg # Call all the output methods 99d4401354Smrg def generate(self): 100d4401354Smrg self.open() 101d4401354Smrg 102d4401354Smrg for (name, item) in self.all: 103d4401354Smrg item.out(name) 104d4401354Smrg 105d4401354Smrg self.close() 106d4401354Smrg 107d4401354Smrg # Keeps track of what's been imported so far. 108d4401354Smrg def add_import(self, name, namespace): 109d4401354Smrg self.imports.append((name, namespace.header)) 110d4401354Smrg 111d4401354Smrg def has_import(self, name): 112d4401354Smrg for (name_, header) in self.imports: 113d4401354Smrg if name_ == name: 114d4401354Smrg return True 115d4401354Smrg return False 116d4401354Smrg 117d4401354Smrg # Keeps track of non-request/event/error datatypes 118d4401354Smrg def add_type(self, id, ns, name, item): 119d4401354Smrg key = ns + id 120d4401354Smrg if key in self.types: 121d4401354Smrg return 122d4401354Smrg self.types[key] = (name, item) 123d4401354Smrg if name[:-1] == self.namespace.prefix: 124d4401354Smrg self.all.append((name, item)) 125d4401354Smrg 126d4401354Smrg def get_type_impl(self, id, idx): 127d4401354Smrg key = id 128d4401354Smrg if key in self.types: 129d4401354Smrg return self.types[key][idx] 130d4401354Smrg 131d4401354Smrg key = self.namespace.ns + id 132d4401354Smrg if key in self.types: 133d4401354Smrg return self.types[key][idx] 134d4401354Smrg 135d4401354Smrg for key in self.types.keys(): 136d4401354Smrg if key.rpartition(':')[2] == id: 137d4401354Smrg return self.types[key][idx] 138d4401354Smrg 139d4401354Smrg raise ResolveException('Type %s not found' % id) 140d4401354Smrg 141d4401354Smrg def get_type(self, id): 142d4401354Smrg return self.get_type_impl(id, 1) 143d4401354Smrg 144d4401354Smrg def get_type_name(self, id): 145d4401354Smrg return self.get_type_impl(id, 0) 146d4401354Smrg 147d4401354Smrg # Keeps track of request datatypes 148d4401354Smrg def add_request(self, id, name, item): 149d4401354Smrg if name[:-1] == self.namespace.prefix: 150d4401354Smrg self.all.append((name, item)) 151d4401354Smrg 152d4401354Smrg # Keeps track of event datatypes 153d4401354Smrg def add_event(self, id, name, item): 154d4401354Smrg self.events[id] = (name, item) 155d4401354Smrg if name[:-1] == self.namespace.prefix: 156d4401354Smrg self.all.append((name, item)) 157d4401354Smrg 158d4401354Smrg def get_event(self, id): 159d4401354Smrg return self.events[id][1] 160d4401354Smrg 161d4401354Smrg # Keeps track of error datatypes 162d4401354Smrg def add_error(self, id, name, item): 163d4401354Smrg self.errors[id] = (name, item) 164d4401354Smrg if name[:-1] == self.namespace.prefix: 165d4401354Smrg self.all.append((name, item)) 166d4401354Smrg 167d4401354Smrg def get_error(self, id): 168d4401354Smrg return self.errors[id][1] 169