Simpler implementation of AttributesUnion for XML processing.
[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 def AttributesUnion(base, **values):
9         baseitems = dict(base)
10         baseitems.update(values)
11         return AttributesImpl(baseitems)
12
13 class AnnotateSize(XMLFilterBase):
14         types = {
15                 'BYTE': 1,
16                 'BOOL': 1,
17                 'CARD8': 1,
18                 'CARD16': 2,
19                 'CARD32': 4,
20                 'INT8': 1,
21                 'INT16': 2,
22                 'INT32': 4,
23                 'float': 4,
24                 'double': 8,
25         }
26         header = None
27         def setTypeSize(self, name, size):
28                 self.types[name] = size
29                 self.types[self.header + ':' + name] = size
30
31         struct = None
32         union = None
33         def startElement(self, name, attrs):
34                 if name == 'xcb':
35                         self.header = attrs['header']
36                 elif name == 'field':
37                         size = self.types.get(attrs['type'], 0)
38                         if self.struct is not None:
39                                 self.totalsize += size
40                         elif self.union is not None:
41                                 self.totalsize = max(self.totalsize, size)
42                         attrs = AttributesUnion(attrs, bytes=str(size))
43                 elif name == 'xidtype':
44                         self.setTypeSize(attrs['name'], 4)
45                 elif name == 'typedef':
46                         self.setTypeSize(attrs['newname'], self.types[attrs['oldname']])
47                 elif name == 'struct' or name == 'union':
48                         assert self.struct is None and self.union is None
49                         setattr(self, name, attrs['name'])
50                         self.totalsize = 0
51                 XMLFilterBase.startElement(self, name, attrs)
52
53         def endElement(self, name):
54                 if name == 'struct' or name == 'union':
55                         assert getattr(self, name) is not None
56                         self.setTypeSize(getattr(self, name), self.totalsize)
57                         setattr(self, name, None)
58                         del self.totalsize
59                 XMLFilterBase.endElement(self, name)
60
61 annotator = AnnotateSize(make_parser())
62 annotator.setContentHandler(XMLGenerator())
63 for f in sys.argv[1:]:
64         annotator.parse(f)