tools/trace: Several tweaks/fixes to dump_state
[mesa.git] / src / gallium / tools / trace / model.py
1 #!/usr/bin/env python
2 ##########################################################################
3 #
4 # Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
5 # All Rights Reserved.
6 #
7 # Permission is hereby granted, free of charge, to any person obtaining a
8 # copy of this software and associated documentation files (the
9 # "Software"), to deal in the Software without restriction, including
10 # without limitation the rights to use, copy, modify, merge, publish,
11 # distribute, sub license, and/or sell copies of the Software, and to
12 # permit persons to whom the Software is furnished to do so, subject to
13 # the following conditions:
14 #
15 # The above copyright notice and this permission notice (including the
16 # next paragraph) shall be included in all copies or substantial portions
17 # of the Software.
18 #
19 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 # IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
23 # ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 #
27 ##########################################################################
28
29
30 '''Trace data model.'''
31
32
33 import sys
34 import string
35 import binascii
36
37 try:
38 from cStringIO import StringIO
39 except ImportError:
40 from StringIO import StringIO
41
42 import format
43
44
45 class Node:
46
47 def visit(self, visitor):
48 raise NotImplementedError
49
50 def __str__(self):
51 stream = StringIO()
52 formatter = format.DefaultFormatter(stream)
53 pretty_printer = PrettyPrinter(formatter)
54 self.visit(pretty_printer)
55 return stream.getvalue()
56
57
58 class Literal(Node):
59
60 def __init__(self, value):
61 self.value = value
62
63 def visit(self, visitor):
64 visitor.visit_literal(self)
65
66
67 class Blob(Node):
68
69 def __init__(self, value):
70 self._rawValue = None
71 self._hexValue = value
72
73 def getValue(self):
74 if self._rawValue is None:
75 self._rawValue = binascii.a2b_hex(self._hexValue)
76 self._hexValue = None
77 return self._rawValue
78
79 def visit(self, visitor):
80 visitor.visit_blob(self)
81
82
83 class NamedConstant(Node):
84
85 def __init__(self, name):
86 self.name = name
87
88 def visit(self, visitor):
89 visitor.visit_named_constant(self)
90
91
92 class Array(Node):
93
94 def __init__(self, elements):
95 self.elements = elements
96
97 def visit(self, visitor):
98 visitor.visit_array(self)
99
100
101 class Struct(Node):
102
103 def __init__(self, name, members):
104 self.name = name
105 self.members = members
106
107 def visit(self, visitor):
108 visitor.visit_struct(self)
109
110
111 class Pointer(Node):
112
113 def __init__(self, address):
114 self.address = address
115
116 def visit(self, visitor):
117 visitor.visit_pointer(self)
118
119
120 class Call:
121
122 def __init__(self, no, klass, method, args, ret, time):
123 self.no = no
124 self.klass = klass
125 self.method = method
126 self.args = args
127 self.ret = ret
128 self.time = time
129
130 def visit(self, visitor):
131 visitor.visit_call(self)
132
133
134 class Trace:
135
136 def __init__(self, calls):
137 self.calls = calls
138
139 def visit(self, visitor):
140 visitor.visit_trace(self)
141
142
143 class Visitor:
144
145 def visit_literal(self, node):
146 raise NotImplementedError
147
148 def visit_blob(self, node):
149 raise NotImplementedError
150
151 def visit_named_constant(self, node):
152 raise NotImplementedError
153
154 def visit_array(self, node):
155 raise NotImplementedError
156
157 def visit_struct(self, node):
158 raise NotImplementedError
159
160 def visit_pointer(self, node):
161 raise NotImplementedError
162
163 def visit_call(self, node):
164 raise NotImplementedError
165
166 def visit_trace(self, node):
167 raise NotImplementedError
168
169
170 class PrettyPrinter:
171
172 def __init__(self, formatter):
173 self.formatter = formatter
174
175 def visit_literal(self, node):
176 if node.value is None:
177 self.formatter.literal('NULL')
178 return
179
180 if isinstance(node.value, basestring):
181 self.formatter.literal('"' + node.value + '"')
182 return
183
184 self.formatter.literal(repr(node.value))
185
186 def visit_blob(self, node):
187 self.formatter.address('blob()')
188
189 def visit_named_constant(self, node):
190 self.formatter.literal(node.name)
191
192 def visit_array(self, node):
193 self.formatter.text('{')
194 sep = ''
195 for value in node.elements:
196 self.formatter.text(sep)
197 value.visit(self)
198 sep = ', '
199 self.formatter.text('}')
200
201 def visit_struct(self, node):
202 self.formatter.text('{')
203 sep = ''
204 for name, value in node.members:
205 self.formatter.text(sep)
206 self.formatter.variable(name)
207 self.formatter.text(' = ')
208 value.visit(self)
209 sep = ', '
210 self.formatter.text('}')
211
212 def visit_pointer(self, node):
213 self.formatter.address(node.address)
214
215 def visit_call(self, node):
216 self.formatter.text('%s ' % node.no)
217 if node.klass is not None:
218 self.formatter.function(node.klass + '::' + node.method)
219 else:
220 self.formatter.function(node.method)
221 self.formatter.text('(')
222 sep = ''
223 for name, value in node.args:
224 self.formatter.text(sep)
225 self.formatter.variable(name)
226 self.formatter.text(' = ')
227 value.visit(self)
228 sep = ', '
229 self.formatter.text(')')
230 if node.ret is not None:
231 self.formatter.text(' = ')
232 node.ret.visit(self)
233 self.formatter.text(' // time ')
234 node.time.visit(self)
235
236 def visit_trace(self, node):
237 for call in node.calls:
238 call.visit(self)
239 self.formatter.newline()
240