state.py revision b26960f7
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 = [] 68b26960f7Smrg self.direct_imports = [] 69b26960f7Smrg self.import_level = 0 70d4401354Smrg self.types = {} 71d4401354Smrg self.events = {} 72d4401354Smrg self.errors = {} 73d4401354Smrg self.all = [] 74d4401354Smrg 75d4401354Smrg # Register some common types 76d4401354Smrg self.add_type('CARD8', '', ('uint8_t',), tcard8) 77d4401354Smrg self.add_type('CARD16', '', ('uint16_t',), tcard16) 78d4401354Smrg self.add_type('CARD32', '', ('uint32_t',), tcard32) 79f591e195Smrg self.add_type('CARD64', '', ('uint64_t',), tcard64) 80d4401354Smrg self.add_type('INT8', '', ('int8_t',), tint8) 81d4401354Smrg self.add_type('INT16', '', ('int16_t',), tint16) 82d4401354Smrg self.add_type('INT32', '', ('int32_t',), tint32) 83f591e195Smrg self.add_type('INT64', '', ('int64_t',), tint64) 84d4401354Smrg self.add_type('BYTE', '', ('uint8_t',), tcard8) 85d4401354Smrg self.add_type('BOOL', '', ('uint8_t',), tcard8) 86d4401354Smrg self.add_type('char', '', ('char',), tchar) 87d4401354Smrg self.add_type('float', '', ('float',), tfloat) 88d4401354Smrg self.add_type('double', '', ('double',), tdouble) 89d4401354Smrg self.add_type('void', '', ('void',), tcard8) 90d4401354Smrg 91d4401354Smrg # This goes out and parses the rest of the XML 92d4401354Smrg def register(self): 93d4401354Smrg matcher.execute(self, self.namespace) 94d4401354Smrg 95d4401354Smrg # Recursively resolve all types 96d4401354Smrg def resolve(self): 97d4401354Smrg for (name, item) in self.all: 98b26960f7Smrg self.pads = 0 99d4401354Smrg item.resolve(self) 100d4401354Smrg 101d4401354Smrg # Call all the output methods 102d4401354Smrg def generate(self): 103d4401354Smrg self.open() 104d4401354Smrg 105d4401354Smrg for (name, item) in self.all: 106d4401354Smrg item.out(name) 107d4401354Smrg 108d4401354Smrg self.close() 109d4401354Smrg 110d4401354Smrg # Keeps track of what's been imported so far. 111d4401354Smrg def add_import(self, name, namespace): 112b26960f7Smrg if self.import_level == 0: 113b26960f7Smrg self.direct_imports.append((name, namespace.header)) 114d4401354Smrg self.imports.append((name, namespace.header)) 115d4401354Smrg 116d4401354Smrg def has_import(self, name): 117d4401354Smrg for (name_, header) in self.imports: 118d4401354Smrg if name_ == name: 119d4401354Smrg return True 120d4401354Smrg return False 121d4401354Smrg 122d4401354Smrg # Keeps track of non-request/event/error datatypes 123d4401354Smrg def add_type(self, id, ns, name, item): 124d4401354Smrg key = ns + id 125d4401354Smrg if key in self.types: 126d4401354Smrg return 127d4401354Smrg self.types[key] = (name, item) 128d4401354Smrg if name[:-1] == self.namespace.prefix: 129d4401354Smrg self.all.append((name, item)) 130d4401354Smrg 131d4401354Smrg def get_type_impl(self, id, idx): 132d4401354Smrg key = id 133d4401354Smrg if key in self.types: 134d4401354Smrg return self.types[key][idx] 135d4401354Smrg 136d4401354Smrg key = self.namespace.ns + id 137d4401354Smrg if key in self.types: 138d4401354Smrg return self.types[key][idx] 139d4401354Smrg 140d4401354Smrg for key in self.types.keys(): 141d4401354Smrg if key.rpartition(':')[2] == id: 142d4401354Smrg return self.types[key][idx] 143d4401354Smrg 144d4401354Smrg raise ResolveException('Type %s not found' % id) 145d4401354Smrg 146d4401354Smrg def get_type(self, id): 147d4401354Smrg return self.get_type_impl(id, 1) 148d4401354Smrg 149d4401354Smrg def get_type_name(self, id): 150d4401354Smrg return self.get_type_impl(id, 0) 151d4401354Smrg 152d4401354Smrg # Keeps track of request datatypes 153d4401354Smrg def add_request(self, id, name, item): 154d4401354Smrg if name[:-1] == self.namespace.prefix: 155d4401354Smrg self.all.append((name, item)) 156d4401354Smrg 157d4401354Smrg # Keeps track of event datatypes 158d4401354Smrg def add_event(self, id, name, item): 159d4401354Smrg self.events[id] = (name, item) 160d4401354Smrg if name[:-1] == self.namespace.prefix: 161d4401354Smrg self.all.append((name, item)) 162d4401354Smrg 163d4401354Smrg def get_event(self, id): 164d4401354Smrg return self.events[id][1] 165d4401354Smrg 166d4401354Smrg # Keeps track of error datatypes 167d4401354Smrg def add_error(self, id, name, item): 168d4401354Smrg self.errors[id] = (name, item) 169d4401354Smrg if name[:-1] == self.namespace.prefix: 170d4401354Smrg self.all.append((name, item)) 171d4401354Smrg 172d4401354Smrg def get_error(self, id): 173d4401354Smrg return self.errors[id][1] 174