made changes to support new value-mask-pad field of valueparam structures
[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, 'BOOL': 1,
16                 'CARD8': 1, 'CARD16': 2, 'CARD32': 4,
17                 'INT8': 1, 'INT16': 2, 'INT32': 4,
18                 'char': 1, 'void': 1,
19                 'float': 4, 'double': 8,
20                 'XID': 4,
21         }
22         header = []
23         def setTypeSize(self, name, size):
24                 assert not self.types.has_key(name), "size of " + name + " declared as both " + str(size) + " and " + str(self.types[name])
25                 self.types[name] = size
26
27         struct = None
28         union = None
29         def startElement(self, name, attrs):
30                 if name == 'xcb':
31                         self.header.insert(0, attrs['header'])
32                 elif name == 'field':
33                         size = self.types.get(attrs['type'], 0)
34                         if self.struct is not None:
35                                 self.totalsize += size
36                         elif self.union is not None:
37                                 self.totalsize = max(self.totalsize, size)
38                         attrs = AttributesUnion(attrs, bytes=str(size))
39                 elif name == 'pad':
40                         assert self.union is None
41                         if self.struct is not None:
42                                 self.totalsize += int(attrs['bytes'])
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
52                 if len(self.header) == 1 or name == 'xcb':
53                         XMLFilterBase.startElement(self, name, attrs)
54
55         def characters(self, content):
56                 if len(self.header) == 1:
57                         XMLFilterBase.characters(self, content)
58
59         def endElement(self, name):
60                 if len(self.header) == 1 or name == 'xcb':
61                         XMLFilterBase.endElement(self, name)
62
63                 if name == 'xcb':
64                         self.header.pop(0)
65                 elif name == 'struct' or name == 'union':
66                         assert getattr(self, name) is not None
67                         self.setTypeSize(getattr(self, name), self.totalsize)
68                         setattr(self, name, None)
69                         del self.totalsize
70
71 annotator = AnnotateSize(make_parser())
72 annotator.setContentHandler(XMLGenerator())
73 if len(sys.argv) > 1:
74         annotator.parse(sys.argv[1])
75 else:
76         annotator.parse(sys.stdin)