symbian-qemu-0.9.1-12/python-win32-2.6.1/lib/hotshot/log.py
changeset 1 2fb8b9db1c86
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/symbian-qemu-0.9.1-12/python-win32-2.6.1/lib/hotshot/log.py	Fri Jul 31 15:01:17 2009 +0100
@@ -0,0 +1,191 @@
+import _hotshot
+import os.path
+import parser
+import symbol
+
+from _hotshot import \
+     WHAT_ENTER, \
+     WHAT_EXIT, \
+     WHAT_LINENO, \
+     WHAT_DEFINE_FILE, \
+     WHAT_DEFINE_FUNC, \
+     WHAT_ADD_INFO
+
+
+__all__ = ["LogReader", "ENTER", "EXIT", "LINE"]
+
+
+ENTER = WHAT_ENTER
+EXIT  = WHAT_EXIT
+LINE  = WHAT_LINENO
+
+
+class LogReader:
+    def __init__(self, logfn):
+        # fileno -> filename
+        self._filemap = {}
+        # (fileno, lineno) -> filename, funcname
+        self._funcmap = {}
+
+        self._reader = _hotshot.logreader(logfn)
+        self._nextitem = self._reader.next
+        self._info = self._reader.info
+        if self._info.has_key('current-directory'):
+            self.cwd = self._info['current-directory']
+        else:
+            self.cwd = None
+
+        # This mirrors the call stack of the profiled code as the log
+        # is read back in.  It contains tuples of the form:
+        #
+        #   (file name, line number of function def, function name)
+        #
+        self._stack = []
+        self._append = self._stack.append
+        self._pop = self._stack.pop
+
+    def close(self):
+        self._reader.close()
+
+    def fileno(self):
+        """Return the file descriptor of the log reader's log file."""
+        return self._reader.fileno()
+
+    def addinfo(self, key, value):
+        """This method is called for each additional ADD_INFO record.
+
+        This can be overridden by applications that want to receive
+        these events.  The default implementation does not need to be
+        called by alternate implementations.
+
+        The initial set of ADD_INFO records do not pass through this
+        mechanism; this is only needed to receive notification when
+        new values are added.  Subclasses can inspect self._info after
+        calling LogReader.__init__().
+        """
+        pass
+
+    def get_filename(self, fileno):
+        try:
+            return self._filemap[fileno]
+        except KeyError:
+            raise ValueError, "unknown fileno"
+
+    def get_filenames(self):
+        return self._filemap.values()
+
+    def get_fileno(self, filename):
+        filename = os.path.normcase(os.path.normpath(filename))
+        for fileno, name in self._filemap.items():
+            if name == filename:
+                return fileno
+        raise ValueError, "unknown filename"
+
+    def get_funcname(self, fileno, lineno):
+        try:
+            return self._funcmap[(fileno, lineno)]
+        except KeyError:
+            raise ValueError, "unknown function location"
+
+    # Iteration support:
+    # This adds an optional (& ignored) parameter to next() so that the
+    # same bound method can be used as the __getitem__() method -- this
+    # avoids using an additional method call which kills the performance.
+
+    def next(self, index=0):
+        while 1:
+            # This call may raise StopIteration:
+            what, tdelta, fileno, lineno = self._nextitem()
+
+            # handle the most common cases first
+
+            if what == WHAT_ENTER:
+                filename, funcname = self._decode_location(fileno, lineno)
+                t = (filename, lineno, funcname)
+                self._append(t)
+                return what, t, tdelta
+
+            if what == WHAT_EXIT:
+                return what, self._pop(), tdelta
+
+            if what == WHAT_LINENO:
+                filename, firstlineno, funcname = self._stack[-1]
+                return what, (filename, lineno, funcname), tdelta
+
+            if what == WHAT_DEFINE_FILE:
+                filename = os.path.normcase(os.path.normpath(tdelta))
+                self._filemap[fileno] = filename
+            elif what == WHAT_DEFINE_FUNC:
+                filename = self._filemap[fileno]
+                self._funcmap[(fileno, lineno)] = (filename, tdelta)
+            elif what == WHAT_ADD_INFO:
+                # value already loaded into self.info; call the
+                # overridable addinfo() handler so higher-level code
+                # can pick up the new value
+                if tdelta == 'current-directory':
+                    self.cwd = lineno
+                self.addinfo(tdelta, lineno)
+            else:
+                raise ValueError, "unknown event type"
+
+    def __iter__(self):
+        return self
+
+    #
+    #  helpers
+    #
+
+    def _decode_location(self, fileno, lineno):
+        try:
+            return self._funcmap[(fileno, lineno)]
+        except KeyError:
+            #
+            # This should only be needed when the log file does not
+            # contain all the DEFINE_FUNC records needed to allow the
+            # function name to be retrieved from the log file.
+            #
+            if self._loadfile(fileno):
+                filename = funcname = None
+            try:
+                filename, funcname = self._funcmap[(fileno, lineno)]
+            except KeyError:
+                filename = self._filemap.get(fileno)
+                funcname = None
+                self._funcmap[(fileno, lineno)] = (filename, funcname)
+        return filename, funcname
+
+    def _loadfile(self, fileno):
+        try:
+            filename = self._filemap[fileno]
+        except KeyError:
+            print "Could not identify fileId", fileno
+            return 1
+        if filename is None:
+            return 1
+        absname = os.path.normcase(os.path.join(self.cwd, filename))
+
+        try:
+            fp = open(absname)
+        except IOError:
+            return
+        st = parser.suite(fp.read())
+        fp.close()
+
+        # Scan the tree looking for def and lambda nodes, filling in
+        # self._funcmap with all the available information.
+        funcdef = symbol.funcdef
+        lambdef = symbol.lambdef
+
+        stack = [st.totuple(1)]
+
+        while stack:
+            tree = stack.pop()
+            try:
+                sym = tree[0]
+            except (IndexError, TypeError):
+                continue
+            if sym == funcdef:
+                self._funcmap[(fileno, tree[2][2])] = filename, tree[2][1]
+            elif sym == lambdef:
+                self._funcmap[(fileno, tree[1][2])] = filename, "<lambda>"
+            stack.extend(list(tree[1:]))