Home | History | Annotate | Download | only in trace
      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 format
     36 
     37 try:
     38     from cStringIO import StringIO
     39 except ImportError:
     40     from StringIO import StringIO
     41 
     42 
     43 class 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 
     56 class 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 
     65 class 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 
     74 class 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 
     83 class 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         
     93 class 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 
    102 class 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 
    115 class Trace:
    116     
    117     def __init__(self, calls):
    118         self.calls = calls
    119         
    120     def visit(self, visitor):
    121         visitor.visit_trace(self)
    122     
    123     
    124 class 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 
    148 class 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