1d4401354Smrg''' 2d4401354SmrgThis module contains the namespace class and the singleton module class. 3d4401354Smrg''' 4d4401354Smrgfrom os.path import dirname, basename 5d5c9b07bSmrgfrom sys import version_info 6d5c9b07bSmrg 7d5c9b07bSmrgif version_info[:2] >= (3, 3): 8d5c9b07bSmrg from xml.etree.ElementTree import parse 9d5c9b07bSmrgelse: 10d5c9b07bSmrg from xml.etree.cElementTree import parse 11d4401354Smrg 12986c8b3dSmrgfrom xcbgen import matcher 13986c8b3dSmrgfrom xcbgen.error import * 14986c8b3dSmrgfrom xcbgen.xtypes import * 15d4401354Smrg 16d4401354Smrgimport __main__ 17d4401354Smrg 18d4401354Smrgclass Namespace(object): 19d4401354Smrg ''' 20d4401354Smrg Contains the naming information for an extension. 21d4401354Smrg 22d4401354Smrg Public fields: 23d4401354Smrg 24d4401354Smrg header is the header attribute ("header file" name). 25d4401354Smrg is_ext is true for extensions, false for xproto. 26d4401354Smrg major_version and minor_version are extension version info. 27d4401354Smrg ext_xname is the X extension name string. 28d4401354Smrg ext_name is the XCB extension name prefix. 29d4401354Smrg ''' 30d4401354Smrg def __init__(self, filename): 31d4401354Smrg # Path info 32d4401354Smrg self.path = filename 33d4401354Smrg self.dir = dirname(filename) 34d4401354Smrg self.file = basename(filename) 35d4401354Smrg 36d4401354Smrg # Parse XML 37d4401354Smrg self.root = parse(filename).getroot() 38d4401354Smrg self.header = self.root.get('header') 39d4401354Smrg self.ns = self.header + ':' 40a27842ffSmrg 41a27842ffSmrg # Events 42a27842ffSmrg self.events = {} 43d4401354Smrg 44d4401354Smrg # Get root element attributes 45d4401354Smrg if self.root.get('extension-xname', False): 46d4401354Smrg self.is_ext = True 47d4401354Smrg self.major_version = self.root.get('major-version') 48d4401354Smrg self.minor_version = self.root.get('minor-version') 49d4401354Smrg self.ext_xname = self.root.get('extension-xname') 50d4401354Smrg self.ext_name = self.root.get('extension-name') 51d4401354Smrg self.prefix = ('xcb', self.ext_name) 52d4401354Smrg else: 53d4401354Smrg self.is_ext = False 54d4401354Smrg self.ext_name = '' 55d4401354Smrg self.prefix = ('xcb',) 56d4401354Smrg 57a27842ffSmrg def add_event(self, id, name, item): 58a27842ffSmrg self.events[id] = (name, item) 59a27842ffSmrg 60a27842ffSmrg def get_event_by_opcode(self, opcode, is_ge_event): 61a27842ffSmrg for id, (name, event) in self.events.items(): 62a27842ffSmrg if event.is_ge_event == is_ge_event: 63a27842ffSmrg opcode_specific_name = event.get_name_for_opcode( opcode ) 64a27842ffSmrg if opcode_specific_name is not None: 65a27842ffSmrg return (opcode_specific_name, event) 66a27842ffSmrg return None 67a27842ffSmrg 68d4401354Smrg 69d4401354Smrgclass Module(object): 70d4401354Smrg ''' 71d4401354Smrg This is the grand, encompassing class that represents an entire XCB specification. 72d4401354Smrg Only gets instantiated once, in the main() routine. 73d4401354Smrg 74d4401354Smrg Don't need to worry about this much except to declare it and to get the namespace. 75d4401354Smrg 76d4401354Smrg Public fields: 77d4401354Smrg namespace contains the namespace info for the spec. 78d4401354Smrg ''' 79d4401354Smrg open = __main__.output['open'] 80d4401354Smrg close = __main__.output['close'] 81d4401354Smrg 82d4401354Smrg def __init__(self, filename, output): 83d4401354Smrg self.namespace = Namespace(filename) 84d4401354Smrg self.output = output 85d4401354Smrg 86d4401354Smrg self.imports = [] 87b26960f7Smrg self.direct_imports = [] 88b26960f7Smrg self.import_level = 0 89d4401354Smrg self.types = {} 90d4401354Smrg self.events = {} 91d4401354Smrg self.errors = {} 92d4401354Smrg self.all = [] 93d4401354Smrg 94a27842ffSmrg # dict of namespaces by ext_name 95a27842ffSmrg self.namespaces = {} 96a27842ffSmrg # enter the main namespace here 97a27842ffSmrg self.namespaces[self.namespace.ext_name] = self.namespace 98a27842ffSmrg 99d4401354Smrg # Register some common types 100d4401354Smrg self.add_type('CARD8', '', ('uint8_t',), tcard8) 101d4401354Smrg self.add_type('CARD16', '', ('uint16_t',), tcard16) 102d4401354Smrg self.add_type('CARD32', '', ('uint32_t',), tcard32) 103f591e195Smrg self.add_type('CARD64', '', ('uint64_t',), tcard64) 104d4401354Smrg self.add_type('INT8', '', ('int8_t',), tint8) 105d4401354Smrg self.add_type('INT16', '', ('int16_t',), tint16) 106d4401354Smrg self.add_type('INT32', '', ('int32_t',), tint32) 107f591e195Smrg self.add_type('INT64', '', ('int64_t',), tint64) 1088d8e295fSmrg self.add_type('BYTE', '', ('uint8_t',), tbyte) 1098d8e295fSmrg self.add_type('BOOL', '', ('uint8_t',), tbool) 110d4401354Smrg self.add_type('char', '', ('char',), tchar) 111d4401354Smrg self.add_type('float', '', ('float',), tfloat) 112d4401354Smrg self.add_type('double', '', ('double',), tdouble) 1138d8e295fSmrg self.add_type('void', '', ('void',), tvoid) 114d4401354Smrg 115d4401354Smrg # This goes out and parses the rest of the XML 116d4401354Smrg def register(self): 117d4401354Smrg matcher.execute(self, self.namespace) 118d4401354Smrg 119d4401354Smrg # Recursively resolve all types 120d4401354Smrg def resolve(self): 121a27842ffSmrg self.add_events_to_namespaces() 122d4401354Smrg for (name, item) in self.all: 123b26960f7Smrg self.pads = 0 124d4401354Smrg item.resolve(self) 125d4401354Smrg 126d4401354Smrg # Call all the output methods 127d4401354Smrg def generate(self): 128d4401354Smrg self.open() 129d4401354Smrg 130d4401354Smrg for (name, item) in self.all: 131d4401354Smrg item.out(name) 132d4401354Smrg 133d4401354Smrg self.close() 134d4401354Smrg 135d4401354Smrg # Keeps track of what's been imported so far. 136d4401354Smrg def add_import(self, name, namespace): 137b26960f7Smrg if self.import_level == 0: 138b26960f7Smrg self.direct_imports.append((name, namespace.header)) 139d4401354Smrg self.imports.append((name, namespace.header)) 140a27842ffSmrg self.namespaces[namespace.ext_name] = namespace 141d4401354Smrg 142d4401354Smrg def has_import(self, name): 143d4401354Smrg for (name_, header) in self.imports: 144d4401354Smrg if name_ == name: 145d4401354Smrg return True 146d4401354Smrg return False 147d4401354Smrg 148d4401354Smrg # Keeps track of non-request/event/error datatypes 149d4401354Smrg def add_type(self, id, ns, name, item): 150d4401354Smrg key = ns + id 151d4401354Smrg if key in self.types: 152d4401354Smrg return 153d4401354Smrg self.types[key] = (name, item) 154d4401354Smrg if name[:-1] == self.namespace.prefix: 155d4401354Smrg self.all.append((name, item)) 156d4401354Smrg 157d4401354Smrg def get_type_impl(self, id, idx): 158d4401354Smrg key = id 159d4401354Smrg if key in self.types: 160d4401354Smrg return self.types[key][idx] 161d4401354Smrg 162d4401354Smrg key = self.namespace.ns + id 163d4401354Smrg if key in self.types: 164d4401354Smrg return self.types[key][idx] 165d4401354Smrg 166d4401354Smrg for key in self.types.keys(): 167d4401354Smrg if key.rpartition(':')[2] == id: 168d4401354Smrg return self.types[key][idx] 169d4401354Smrg 170d4401354Smrg raise ResolveException('Type %s not found' % id) 171d4401354Smrg 172d4401354Smrg def get_type(self, id): 173d4401354Smrg return self.get_type_impl(id, 1) 174d4401354Smrg 175d4401354Smrg def get_type_name(self, id): 176d4401354Smrg return self.get_type_impl(id, 0) 177d4401354Smrg 178a27842ffSmrg def get_namespace(self, ext_name): 179a27842ffSmrg return self.namespaces[ext_name] 180a27842ffSmrg 181d4401354Smrg # Keeps track of request datatypes 182d4401354Smrg def add_request(self, id, name, item): 183d4401354Smrg if name[:-1] == self.namespace.prefix: 184d4401354Smrg self.all.append((name, item)) 185d4401354Smrg 186d4401354Smrg # Keeps track of event datatypes 187d4401354Smrg def add_event(self, id, name, item): 188d4401354Smrg self.events[id] = (name, item) 189d4401354Smrg if name[:-1] == self.namespace.prefix: 190d4401354Smrg self.all.append((name, item)) 191d4401354Smrg 192a27842ffSmrg 193a27842ffSmrg def add_events_to_namespaces(self): 194a27842ffSmrg # add to its namespace object 195a27842ffSmrg for id, (name,item) in self.events.items(): 196a27842ffSmrg if name[:-1] == ('xcb',): 197a27842ffSmrg # core event 198a27842ffSmrg namespace_name = '' 199a27842ffSmrg else: 200a27842ffSmrg # extension event 201a27842ffSmrg namespace_name = name[-2] 202a27842ffSmrg 203a27842ffSmrg namespace = self.namespaces[namespace_name] 204a27842ffSmrg 205a27842ffSmrg if namespace is not None: 206a27842ffSmrg namespace.add_event(id, name, item) 207a27842ffSmrg 208a27842ffSmrg 209d4401354Smrg def get_event(self, id): 210d4401354Smrg return self.events[id][1] 211d4401354Smrg 212d4401354Smrg # Keeps track of error datatypes 213d4401354Smrg def add_error(self, id, name, item): 214d4401354Smrg self.errors[id] = (name, item) 215d4401354Smrg if name[:-1] == self.namespace.prefix: 216d4401354Smrg self.all.append((name, item)) 217d4401354Smrg 218d4401354Smrg def get_error(self, id): 219d4401354Smrg return self.errors[id][1] 220