Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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.