2 This module contains the namespace class and the singleton module class.
4 from os.path import dirname, basename
5 from xml.etree.cElementTree import parse
7 from xcbgen import matcher
8 from xcbgen.error import *
9 from xcbgen.xtypes import *
13 class Namespace(object):
15 Contains the naming information for an extension.
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.
25 def __init__(self, filename):
28 self.dir = dirname(filename)
29 self.file = basename(filename)
32 self.root = parse(filename).getroot()
33 self.header = self.root.get('header')
34 self.ns = self.header + ':'
36 # Get root element attributes
37 if self.root.get('extension-xname', False):
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)
47 self.prefix = ('xcb',)
52 This is the grand, encompassing class that represents an entire XCB specification.
53 Only gets instantiated once, in the main() routine.
55 Don't need to worry about this much except to declare it and to get the namespace.
58 namespace contains the namespace info for the spec.
60 open = __main__.output['open']
61 close = __main__.output['close']
63 def __init__(self, filename, output):
64 self.namespace = Namespace(filename)
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('INT8', '', ('int8_t',), tint8)
78 self.add_type('INT16', '', ('int16_t',), tint16)
79 self.add_type('INT32', '', ('int32_t',), tint32)
80 self.add_type('BYTE', '', ('uint8_t',), tcard8)
81 self.add_type('BOOL', '', ('uint8_t',), tcard8)
82 self.add_type('char', '', ('char',), tchar)
83 self.add_type('float', '', ('float',), tfloat)
84 self.add_type('double', '', ('double',), tdouble)
85 self.add_type('void', '', ('void',), tcard8)
87 # This goes out and parses the rest of the XML
89 matcher.execute(self, self.namespace)
91 # Recursively resolve all types
93 for (name, item) in self.all:
96 # Call all the output methods
100 for (name, item) in self.all:
105 # Keeps track of what's been imported so far.
106 def add_import(self, name, namespace):
107 self.imports.append((name, namespace.header))
109 def has_import(self, name):
110 for (name_, header) in self.imports:
115 # Keeps track of non-request/event/error datatypes
116 def add_type(self, id, ns, name, item):
118 if key in self.types:
120 self.types[key] = (name, item)
121 if name[:-1] == self.namespace.prefix:
122 self.all.append((name, item))
124 def get_type_impl(self, id, idx):
126 if key in self.types:
127 return self.types[key][idx]
129 key = self.namespace.ns + id
130 if key in self.types:
131 return self.types[key][idx]
133 for key in self.types.keys():
134 if key.rpartition(':')[2] == id:
135 return self.types[key][idx]
137 raise ResolveException('Type %s not found' % id)
139 def get_type(self, id):
140 return self.get_type_impl(id, 1)
142 def get_type_name(self, id):
143 return self.get_type_impl(id, 0)
145 # Keeps track of request datatypes
146 def add_request(self, id, name, item):
147 if name[:-1] == self.namespace.prefix:
148 self.all.append((name, item))
150 # Keeps track of event datatypes
151 def add_event(self, id, name, item):
152 self.events[id] = (name, item)
153 if name[:-1] == self.namespace.prefix:
154 self.all.append((name, item))
156 def get_event(self, id):
157 return self.events[id][1]
159 # Keeps track of error datatypes
160 def add_error(self, id, name, item):
161 self.errors[id] = (name, item)
162 if name[:-1] == self.namespace.prefix:
163 self.all.append((name, item))
165 def get_error(self, id):
166 return self.errors[id][1]