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 33import sys 34import string 35import format 36 37try: 38 from cStringIO import StringIO 39except ImportError: 40 from StringIO import StringIO 41 42 43class Node: 44 45 def visit(self, visitor): 46 raise NotImplementedError 47 48 def __str__(self): 49 stream = StringIO() 50 formatter = format.DefaultFormatter(stream) 51 pretty_printer = PrettyPrinter(formatter) 52 self.visit(pretty_printer) 53 return stream.getvalue() 54 55 56class Literal(Node): 57 58 def __init__(self, value): 59 self.value = value 60 61 def visit(self, visitor): 62 visitor.visit_literal(self) 63 64 65class NamedConstant(Node): 66 67 def __init__(self, name): 68 self.name = name 69 70 def visit(self, visitor): 71 visitor.visit_named_constant(self) 72 73 74class Array(Node): 75 76 def __init__(self, elements): 77 self.elements = elements 78 79 def visit(self, visitor): 80 visitor.visit_array(self) 81 82 83class Struct(Node): 84 85 def __init__(self, name, members): 86 self.name = name 87 self.members = members 88 89 def visit(self, visitor): 90 visitor.visit_struct(self) 91 92 93class Pointer(Node): 94 95 def __init__(self, address): 96 self.address = address 97 98 def visit(self, visitor): 99 visitor.visit_pointer(self) 100 101 102class Call: 103 104 def __init__(self, no, klass, method, args, ret): 105 self.no = no 106 self.klass = klass 107 self.method = method 108 self.args = args 109 self.ret = ret 110 111 def visit(self, visitor): 112 visitor.visit_call(self) 113 114 115class Trace: 116 117 def __init__(self, calls): 118 self.calls = calls 119 120 def visit(self, visitor): 121 visitor.visit_trace(self) 122 123 124class Visitor: 125 126 def visit_literal(self, node): 127 raise NotImplementedError 128 129 def visit_named_constant(self, node): 130 raise NotImplementedError 131 132 def visit_array(self, node): 133 raise NotImplementedError 134 135 def visit_struct(self, node): 136 raise NotImplementedError 137 138 def visit_pointer(self, node): 139 raise NotImplementedError 140 141 def visit_call(self, node): 142 raise NotImplementedError 143 144 def visit_trace(self, node): 145 raise NotImplementedError 146 147 148class PrettyPrinter: 149 150 def __init__(self, formatter): 151 self.formatter = formatter 152 153 def visit_literal(self, node): 154 if node.value is None: 155 self.formatter.literal('NULL') 156 return 157 158 if isinstance(node.value, basestring): 159 if len(node.value) >= 4096 or node.value.strip(string.printable): 160 self.formatter.address('blob(%u)' % len(node.value)) 161 #self.formatter.text('...') 162 return 163 164 self.formatter.literal('"' + node.value + '"') 165 return 166 167 self.formatter.literal(repr(node.value)) 168 169 def visit_named_constant(self, node): 170 self.formatter.literal(node.name) 171 172 def visit_array(self, node): 173 self.formatter.text('{') 174 sep = '' 175 for value in node.elements: 176 self.formatter.text(sep) 177 value.visit(self) 178 sep = ', ' 179 self.formatter.text('}') 180 181 def visit_struct(self, node): 182 self.formatter.text('{') 183 sep = '' 184 for name, value in node.members: 185 self.formatter.text(sep) 186 self.formatter.variable(name) 187 self.formatter.text(' = ') 188 value.visit(self) 189 sep = ', ' 190 self.formatter.text('}') 191 192 def visit_pointer(self, node): 193 self.formatter.address(node.address) 194 195 def visit_call(self, node): 196 self.formatter.text('%s ' % node.no) 197 if node.klass is not None: 198 self.formatter.function(node.klass + '::' + node.method) 199 else: 200 self.formatter.function(node.method) 201 self.formatter.text('(') 202 sep = '' 203 for name, value in node.args: 204 self.formatter.text(sep) 205 self.formatter.variable(name) 206 self.formatter.text(' = ') 207 value.visit(self) 208 sep = ', ' 209 self.formatter.text(')') 210 if node.ret is not None: 211 self.formatter.text(' = ') 212 node.ret.visit(self) 213 214 def visit_trace(self, node): 215 for call in node.calls: 216 call.visit(self) 217 self.formatter.newline() 218 219