Home | History | Annotate | Download | only in trace
      1 #!/usr/bin/env python
      2 ##########################################################################
      3 # 
      4 # Copyright 2008 VMware, Inc.
      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 VMWARE 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         if node.time is not None:
    234             self.formatter.text(' // time ')
    235             node.time.visit(self)
    236 
    237     def visit_trace(self, node):
    238         for call in node.calls:
    239             call.visit(self)
    240             self.formatter.newline()
    241 
    242