--- /dev/null
+#!/usr/bin/python
+
+from xml.sax.saxutils import XMLFilterBase, XMLGenerator
+from xml.sax import make_parser
+import sys, os
+
+path = [os.path.curdir, 'extensions']
+def find_file_on_path(name):
+ for d in path:
+ test = os.path.join(d, name)
+ if os.path.isfile(test):
+ return test
+ raise OSError(errno.ENOENT, os.strerror(errno.ENOENT), name)
+
+seen = {}
+
+class ProcessImports(XMLFilterBase):
+ def setContentHandler(self, handler):
+ self.handler = handler
+ XMLFilterBase.setContentHandler(self, handler)
+
+ def ensure(self, name):
+ if not seen.has_key(name):
+ child = ProcessImports(make_parser())
+ child.setContentHandler(self.handler)
+ child.parse(find_file_on_path(name + '.xml'))
+
+ def startDocument(self):
+ pass
+ def endDocument(self):
+ pass
+
+ inimport = None
+
+ def startElement(self, name, attrs):
+ assert self.inimport is None
+ if name == 'import':
+ self.inimport = ""
+ return
+ XMLFilterBase.startElement(self, name, attrs)
+ if name == 'xcb':
+ seen[attrs['header']] = True
+ if attrs['header'] != 'xcb_types':
+ self.ensure('xcb_types')
+ self.ensure('xproto')
+
+ def characters(self, content):
+ if self.inimport is not None:
+ self.inimport += content
+ else:
+ XMLFilterBase.characters(self, content)
+
+ def endElement(self, name):
+ if name == 'import':
+ self.ensure(self.inimport)
+ self.inimport = None
+ return
+ XMLFilterBase.endElement(self, name)
+
+out = XMLGenerator()
+importer = ProcessImports(make_parser())
+importer.setContentHandler(out)
+out.startDocument()
+if len(sys.argv) > 1:
+ importer.parse(sys.argv[1])
+else:
+ importer.parse(sys.stdin)
+out.endDocument()
'float': 4,
'double': 8,
}
- header = None
+ header = []
def setTypeSize(self, name, size):
self.types[name] = size
- self.types[self.header + ':' + name] = size
+ self.types[self.header[0] + ':' + name] = size
struct = None
union = None
def startElement(self, name, attrs):
if name == 'xcb':
- self.header = attrs['header']
+ self.header.insert(0, attrs['header'])
elif name == 'field':
size = self.types.get(attrs['type'], 0)
if self.struct is not None:
assert self.struct is None and self.union is None
setattr(self, name, attrs['name'])
self.totalsize = 0
- XMLFilterBase.startElement(self, name, attrs)
+
+ if len(self.header) == 1:
+ XMLFilterBase.startElement(self, name, attrs)
+
+ def characters(self, content):
+ if len(self.header) == 1:
+ XMLFilterBase.characters(self, content)
def endElement(self, name):
- if name == 'struct' or name == 'union':
+ if len(self.header) == 1:
+ XMLFilterBase.endElement(self, name)
+
+ if name == 'xcb':
+ self.header.pop(0)
+ elif name == 'struct' or name == 'union':
assert getattr(self, name) is not None
self.setTypeSize(getattr(self, name), self.totalsize)
setattr(self, name, None)
del self.totalsize
- XMLFilterBase.endElement(self, name)
annotator = AnnotateSize(make_parser())
annotator.setContentHandler(XMLGenerator())
-for f in sys.argv[1:]:
- annotator.parse(f)
+if len(sys.argv) > 1:
+ annotator.parse(sys.argv[1])
+else:
+ annotator.parse(sys.stdin)