New tool to annotate XML-XCB <field>s with their size in bytes.
[free-sw/xcb/proto] / src / size.py
1 #!/usr/bin/python
2
3 from xml.sax.saxutils import XMLFilterBase, XMLGenerator
4 from xml.sax.xmlreader import AttributesImpl
5 from xml.sax import make_parser
6 import sys
7
8 class AttributesUnion(AttributesImpl):
9         def __init__(self, base, **values):
10                 baseitems = dict(base)
11                 baseitems.update(values)
12                 AttributesImpl.__init__(self, baseitems)
13
14 class AnnotateSize(XMLFilterBase):
15         types = {
16                 'BYTE': 1,
17                 'BOOL': 1,
18                 'CARD8': 1,
19                 'CARD16': 2,
20                 'CARD32': 4,
21                 'INT8': 1,
22                 'INT16': 2,
23                 'INT32': 4,
24                 'float': 4,
25                 'double': 8,
26         }
27         header = None
28         def setTypeSize(self, name, size):
29                 self.types[name] = size
30                 self.types[self.header + ':' + name] = size
31
32         struct = None
33         union = None
34         def startElement(self, name, attrs):
35                 if name == 'xcb':
36                         self.header = attrs['header']
37                 elif name == 'field':
38                         size = self.types.get(attrs['type'], 0)
39                         if self.struct is not None:
40                                 self.totalsize += size
41                         elif self.union is not None:
42                                 self.totalsize = max(self.totalsize, size)
43                         attrs = AttributesUnion(attrs, bytes=str(size))
44                 elif name == 'xidtype':
45                         self.setTypeSize(attrs['name'], 4)
46                 elif name == 'typedef':
47                         self.setTypeSize(attrs['newname'], self.types[attrs['oldname']])
48                 elif name == 'struct' or name == 'union':
49                         assert self.struct is None and self.union is None
50                         setattr(self, name, attrs['name'])
51                         self.totalsize = 0
52                 XMLFilterBase.startElement(self, name, attrs)
53
54         def endElement(self, name):
55                 if name == 'struct' or name == 'union':
56                         assert getattr(self, name) is not None
57                         self.setTypeSize(getattr(self, name), self.totalsize)
58                         setattr(self, name, None)
59                         del self.totalsize
60                 XMLFilterBase.endElement(self, name)
61
62 annotator = AnnotateSize(make_parser())
63 annotator.setContentHandler(XMLGenerator())
64 for f in sys.argv[1:]:
65         annotator.parse(f)