Process <import> directives with a new import.py tool.
authorJamey Sharp <jamey@minilop.net>
Wed, 14 Jun 2006 00:23:03 +0000 (17:23 -0700)
committerJamey Sharp <jamey@minilop.net>
Wed, 14 Jun 2006 00:23:03 +0000 (17:23 -0700)
Update size.py to accept all the data it needs in one file or stdin.

src/import.py [new file with mode: 0755]
src/size.py

diff --git a/src/import.py b/src/import.py
new file mode 100755 (executable)
index 0000000..63cba99
--- /dev/null
@@ -0,0 +1,68 @@
+#!/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()
index 2e1c403..07e2f27 100755 (executable)
@@ -23,16 +23,16 @@ class AnnotateSize(XMLFilterBase):
                '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:
@@ -48,17 +48,29 @@ class AnnotateSize(XMLFilterBase):
                        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)