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