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