]> git.proxmox.com Git - mirror_edk2.git/blobdiff - AppPkg/Applications/Python/Python-2.7.2/Lib/pstats.py
edk2: Remove AppPkg, StdLib, StdLibPrivateInternalFiles
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Lib / pstats.py
diff --git a/AppPkg/Applications/Python/Python-2.7.2/Lib/pstats.py b/AppPkg/Applications/Python/Python-2.7.2/Lib/pstats.py
deleted file mode 100644 (file)
index 98aae30..0000000
+++ /dev/null
@@ -1,713 +0,0 @@
-"""Class for printing reports on profiled python code."""\r
-\r
-# Class for printing reports on profiled python code. rev 1.0  4/1/94\r
-#\r
-# Based on prior profile module by Sjoerd Mullender...\r
-#   which was hacked somewhat by: Guido van Rossum\r
-#\r
-# see profile.py for more info.\r
-\r
-# Copyright 1994, by InfoSeek Corporation, all rights reserved.\r
-# Written by James Roskind\r
-#\r
-# Permission to use, copy, modify, and distribute this Python software\r
-# and its associated documentation for any purpose (subject to the\r
-# restriction in the following sentence) without fee is hereby granted,\r
-# provided that the above copyright notice appears in all copies, and\r
-# that both that copyright notice and this permission notice appear in\r
-# supporting documentation, and that the name of InfoSeek not be used in\r
-# advertising or publicity pertaining to distribution of the software\r
-# without specific, written prior permission.  This permission is\r
-# explicitly restricted to the copying and modification of the software\r
-# to remain in Python, compiled Python, or other languages (such as C)\r
-# wherein the modified or derived code is exclusively imported into a\r
-# Python module.\r
-#\r
-# INFOSEEK CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS\r
-# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND\r
-# FITNESS. IN NO EVENT SHALL INFOSEEK CORPORATION BE LIABLE FOR ANY\r
-# SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER\r
-# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF\r
-# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN\r
-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\r
-\r
-\r
-import sys\r
-import os\r
-import time\r
-import marshal\r
-import re\r
-from functools import cmp_to_key\r
-\r
-__all__ = ["Stats"]\r
-\r
-class Stats:\r
-    """This class is used for creating reports from data generated by the\r
-    Profile class.  It is a "friend" of that class, and imports data either\r
-    by direct access to members of Profile class, or by reading in a dictionary\r
-    that was emitted (via marshal) from the Profile class.\r
-\r
-    The big change from the previous Profiler (in terms of raw functionality)\r
-    is that an "add()" method has been provided to combine Stats from\r
-    several distinct profile runs.  Both the constructor and the add()\r
-    method now take arbitrarily many file names as arguments.\r
-\r
-    All the print methods now take an argument that indicates how many lines\r
-    to print.  If the arg is a floating point number between 0 and 1.0, then\r
-    it is taken as a decimal percentage of the available lines to be printed\r
-    (e.g., .1 means print 10% of all available lines).  If it is an integer,\r
-    it is taken to mean the number of lines of data that you wish to have\r
-    printed.\r
-\r
-    The sort_stats() method now processes some additional options (i.e., in\r
-    addition to the old -1, 0, 1, or 2).  It takes an arbitrary number of\r
-    quoted strings to select the sort order.  For example sort_stats('time',\r
-    'name') sorts on the major key of 'internal function time', and on the\r
-    minor key of 'the name of the function'.  Look at the two tables in\r
-    sort_stats() and get_sort_arg_defs(self) for more examples.\r
-\r
-    All methods return self, so you can string together commands like:\r
-        Stats('foo', 'goo').strip_dirs().sort_stats('calls').\\r
-                            print_stats(5).print_callers(5)\r
-    """\r
-\r
-    def __init__(self, *args, **kwds):\r
-        # I can't figure out how to explictly specify a stream keyword arg\r
-        # with *args:\r
-        #   def __init__(self, *args, stream=sys.stdout): ...\r
-        # so I use **kwds and sqauwk if something unexpected is passed in.\r
-        self.stream = sys.stdout\r
-        if "stream" in kwds:\r
-            self.stream = kwds["stream"]\r
-            del kwds["stream"]\r
-        if kwds:\r
-            keys = kwds.keys()\r
-            keys.sort()\r
-            extras = ", ".join(["%s=%s" % (k, kwds[k]) for k in keys])\r
-            raise ValueError, "unrecognized keyword args: %s" % extras\r
-        if not len(args):\r
-            arg = None\r
-        else:\r
-            arg = args[0]\r
-            args = args[1:]\r
-        self.init(arg)\r
-        self.add(*args)\r
-\r
-    def init(self, arg):\r
-        self.all_callees = None  # calc only if needed\r
-        self.files = []\r
-        self.fcn_list = None\r
-        self.total_tt = 0\r
-        self.total_calls = 0\r
-        self.prim_calls = 0\r
-        self.max_name_len = 0\r
-        self.top_level = {}\r
-        self.stats = {}\r
-        self.sort_arg_dict = {}\r
-        self.load_stats(arg)\r
-        trouble = 1\r
-        try:\r
-            self.get_top_level_stats()\r
-            trouble = 0\r
-        finally:\r
-            if trouble:\r
-                print >> self.stream, "Invalid timing data",\r
-                if self.files: print >> self.stream, self.files[-1],\r
-                print >> self.stream\r
-\r
-    def load_stats(self, arg):\r
-        if not arg:  self.stats = {}\r
-        elif isinstance(arg, basestring):\r
-            f = open(arg, 'rb')\r
-            self.stats = marshal.load(f)\r
-            f.close()\r
-            try:\r
-                file_stats = os.stat(arg)\r
-                arg = time.ctime(file_stats.st_mtime) + "    " + arg\r
-            except:  # in case this is not unix\r
-                pass\r
-            self.files = [ arg ]\r
-        elif hasattr(arg, 'create_stats'):\r
-            arg.create_stats()\r
-            self.stats = arg.stats\r
-            arg.stats = {}\r
-        if not self.stats:\r
-            raise TypeError,  "Cannot create or construct a %r object from '%r''" % (\r
-                              self.__class__, arg)\r
-        return\r
-\r
-    def get_top_level_stats(self):\r
-        for func, (cc, nc, tt, ct, callers) in self.stats.items():\r
-            self.total_calls += nc\r
-            self.prim_calls  += cc\r
-            self.total_tt    += tt\r
-            if ("jprofile", 0, "profiler") in callers:\r
-                self.top_level[func] = None\r
-            if len(func_std_string(func)) > self.max_name_len:\r
-                self.max_name_len = len(func_std_string(func))\r
-\r
-    def add(self, *arg_list):\r
-        if not arg_list: return self\r
-        if len(arg_list) > 1: self.add(*arg_list[1:])\r
-        other = arg_list[0]\r
-        if type(self) != type(other) or self.__class__ != other.__class__:\r
-            other = Stats(other)\r
-        self.files += other.files\r
-        self.total_calls += other.total_calls\r
-        self.prim_calls += other.prim_calls\r
-        self.total_tt += other.total_tt\r
-        for func in other.top_level:\r
-            self.top_level[func] = None\r
-\r
-        if self.max_name_len < other.max_name_len:\r
-            self.max_name_len = other.max_name_len\r
-\r
-        self.fcn_list = None\r
-\r
-        for func, stat in other.stats.iteritems():\r
-            if func in self.stats:\r
-                old_func_stat = self.stats[func]\r
-            else:\r
-                old_func_stat = (0, 0, 0, 0, {},)\r
-            self.stats[func] = add_func_stats(old_func_stat, stat)\r
-        return self\r
-\r
-    def dump_stats(self, filename):\r
-        """Write the profile data to a file we know how to load back."""\r
-        f = file(filename, 'wb')\r
-        try:\r
-            marshal.dump(self.stats, f)\r
-        finally:\r
-            f.close()\r
-\r
-    # list the tuple indices and directions for sorting,\r
-    # along with some printable description\r
-    sort_arg_dict_default = {\r
-              "calls"     : (((1,-1),              ), "call count"),\r
-              "cumulative": (((3,-1),              ), "cumulative time"),\r
-              "file"      : (((4, 1),              ), "file name"),\r
-              "line"      : (((5, 1),              ), "line number"),\r
-              "module"    : (((4, 1),              ), "file name"),\r
-              "name"      : (((6, 1),              ), "function name"),\r
-              "nfl"       : (((6, 1),(4, 1),(5, 1),), "name/file/line"),\r
-              "pcalls"    : (((0,-1),              ), "call count"),\r
-              "stdname"   : (((7, 1),              ), "standard name"),\r
-              "time"      : (((2,-1),              ), "internal time"),\r
-              }\r
-\r
-    def get_sort_arg_defs(self):\r
-        """Expand all abbreviations that are unique."""\r
-        if not self.sort_arg_dict:\r
-            self.sort_arg_dict = dict = {}\r
-            bad_list = {}\r
-            for word, tup in self.sort_arg_dict_default.iteritems():\r
-                fragment = word\r
-                while fragment:\r
-                    if not fragment:\r
-                        break\r
-                    if fragment in dict:\r
-                        bad_list[fragment] = 0\r
-                        break\r
-                    dict[fragment] = tup\r
-                    fragment = fragment[:-1]\r
-            for word in bad_list:\r
-                del dict[word]\r
-        return self.sort_arg_dict\r
-\r
-    def sort_stats(self, *field):\r
-        if not field:\r
-            self.fcn_list = 0\r
-            return self\r
-        if len(field) == 1 and isinstance(field[0], (int, long)):\r
-            # Be compatible with old profiler\r
-            field = [ {-1: "stdname",\r
-                       0:  "calls",\r
-                       1:  "time",\r
-                       2:  "cumulative"}[field[0]] ]\r
-\r
-        sort_arg_defs = self.get_sort_arg_defs()\r
-        sort_tuple = ()\r
-        self.sort_type = ""\r
-        connector = ""\r
-        for word in field:\r
-            sort_tuple = sort_tuple + sort_arg_defs[word][0]\r
-            self.sort_type += connector + sort_arg_defs[word][1]\r
-            connector = ", "\r
-\r
-        stats_list = []\r
-        for func, (cc, nc, tt, ct, callers) in self.stats.iteritems():\r
-            stats_list.append((cc, nc, tt, ct) + func +\r
-                              (func_std_string(func), func))\r
-\r
-        stats_list.sort(key=cmp_to_key(TupleComp(sort_tuple).compare))\r
-\r
-        self.fcn_list = fcn_list = []\r
-        for tuple in stats_list:\r
-            fcn_list.append(tuple[-1])\r
-        return self\r
-\r
-    def reverse_order(self):\r
-        if self.fcn_list:\r
-            self.fcn_list.reverse()\r
-        return self\r
-\r
-    def strip_dirs(self):\r
-        oldstats = self.stats\r
-        self.stats = newstats = {}\r
-        max_name_len = 0\r
-        for func, (cc, nc, tt, ct, callers) in oldstats.iteritems():\r
-            newfunc = func_strip_path(func)\r
-            if len(func_std_string(newfunc)) > max_name_len:\r
-                max_name_len = len(func_std_string(newfunc))\r
-            newcallers = {}\r
-            for func2, caller in callers.iteritems():\r
-                newcallers[func_strip_path(func2)] = caller\r
-\r
-            if newfunc in newstats:\r
-                newstats[newfunc] = add_func_stats(\r
-                                        newstats[newfunc],\r
-                                        (cc, nc, tt, ct, newcallers))\r
-            else:\r
-                newstats[newfunc] = (cc, nc, tt, ct, newcallers)\r
-        old_top = self.top_level\r
-        self.top_level = new_top = {}\r
-        for func in old_top:\r
-            new_top[func_strip_path(func)] = None\r
-\r
-        self.max_name_len = max_name_len\r
-\r
-        self.fcn_list = None\r
-        self.all_callees = None\r
-        return self\r
-\r
-    def calc_callees(self):\r
-        if self.all_callees: return\r
-        self.all_callees = all_callees = {}\r
-        for func, (cc, nc, tt, ct, callers) in self.stats.iteritems():\r
-            if not func in all_callees:\r
-                all_callees[func] = {}\r
-            for func2, caller in callers.iteritems():\r
-                if not func2 in all_callees:\r
-                    all_callees[func2] = {}\r
-                all_callees[func2][func]  = caller\r
-        return\r
-\r
-    #******************************************************************\r
-    # The following functions support actual printing of reports\r
-    #******************************************************************\r
-\r
-    # Optional "amount" is either a line count, or a percentage of lines.\r
-\r
-    def eval_print_amount(self, sel, list, msg):\r
-        new_list = list\r
-        if isinstance(sel, basestring):\r
-            try:\r
-                rex = re.compile(sel)\r
-            except re.error:\r
-                msg += "   <Invalid regular expression %r>\n" % sel\r
-                return new_list, msg\r
-            new_list = []\r
-            for func in list:\r
-                if rex.search(func_std_string(func)):\r
-                    new_list.append(func)\r
-        else:\r
-            count = len(list)\r
-            if isinstance(sel, float) and 0.0 <= sel < 1.0:\r
-                count = int(count * sel + .5)\r
-                new_list = list[:count]\r
-            elif isinstance(sel, (int, long)) and 0 <= sel < count:\r
-                count = sel\r
-                new_list = list[:count]\r
-        if len(list) != len(new_list):\r
-            msg += "   List reduced from %r to %r due to restriction <%r>\n" % (\r
-                len(list), len(new_list), sel)\r
-\r
-        return new_list, msg\r
-\r
-    def get_print_list(self, sel_list):\r
-        width = self.max_name_len\r
-        if self.fcn_list:\r
-            stat_list = self.fcn_list[:]\r
-            msg = "   Ordered by: " + self.sort_type + '\n'\r
-        else:\r
-            stat_list = self.stats.keys()\r
-            msg = "   Random listing order was used\n"\r
-\r
-        for selection in sel_list:\r
-            stat_list, msg = self.eval_print_amount(selection, stat_list, msg)\r
-\r
-        count = len(stat_list)\r
-\r
-        if not stat_list:\r
-            return 0, stat_list\r
-        print >> self.stream, msg\r
-        if count < len(self.stats):\r
-            width = 0\r
-            for func in stat_list:\r
-                if  len(func_std_string(func)) > width:\r
-                    width = len(func_std_string(func))\r
-        return width+2, stat_list\r
-\r
-    def print_stats(self, *amount):\r
-        for filename in self.files:\r
-            print >> self.stream, filename\r
-        if self.files: print >> self.stream\r
-        indent = ' ' * 8\r
-        for func in self.top_level:\r
-            print >> self.stream, indent, func_get_function_name(func)\r
-\r
-        print >> self.stream, indent, self.total_calls, "function calls",\r
-        if self.total_calls != self.prim_calls:\r
-            print >> self.stream, "(%d primitive calls)" % self.prim_calls,\r
-        print >> self.stream, "in %.3f seconds" % self.total_tt\r
-        print >> self.stream\r
-        width, list = self.get_print_list(amount)\r
-        if list:\r
-            self.print_title()\r
-            for func in list:\r
-                self.print_line(func)\r
-            print >> self.stream\r
-            print >> self.stream\r
-        return self\r
-\r
-    def print_callees(self, *amount):\r
-        width, list = self.get_print_list(amount)\r
-        if list:\r
-            self.calc_callees()\r
-\r
-            self.print_call_heading(width, "called...")\r
-            for func in list:\r
-                if func in self.all_callees:\r
-                    self.print_call_line(width, func, self.all_callees[func])\r
-                else:\r
-                    self.print_call_line(width, func, {})\r
-            print >> self.stream\r
-            print >> self.stream\r
-        return self\r
-\r
-    def print_callers(self, *amount):\r
-        width, list = self.get_print_list(amount)\r
-        if list:\r
-            self.print_call_heading(width, "was called by...")\r
-            for func in list:\r
-                cc, nc, tt, ct, callers = self.stats[func]\r
-                self.print_call_line(width, func, callers, "<-")\r
-            print >> self.stream\r
-            print >> self.stream\r
-        return self\r
-\r
-    def print_call_heading(self, name_size, column_title):\r
-        print >> self.stream, "Function ".ljust(name_size) + column_title\r
-        # print sub-header only if we have new-style callers\r
-        subheader = False\r
-        for cc, nc, tt, ct, callers in self.stats.itervalues():\r
-            if callers:\r
-                value = callers.itervalues().next()\r
-                subheader = isinstance(value, tuple)\r
-                break\r
-        if subheader:\r
-            print >> self.stream, " "*name_size + "    ncalls  tottime  cumtime"\r
-\r
-    def print_call_line(self, name_size, source, call_dict, arrow="->"):\r
-        print >> self.stream, func_std_string(source).ljust(name_size) + arrow,\r
-        if not call_dict:\r
-            print >> self.stream\r
-            return\r
-        clist = call_dict.keys()\r
-        clist.sort()\r
-        indent = ""\r
-        for func in clist:\r
-            name = func_std_string(func)\r
-            value = call_dict[func]\r
-            if isinstance(value, tuple):\r
-                nc, cc, tt, ct = value\r
-                if nc != cc:\r
-                    substats = '%d/%d' % (nc, cc)\r
-                else:\r
-                    substats = '%d' % (nc,)\r
-                substats = '%s %s %s  %s' % (substats.rjust(7+2*len(indent)),\r
-                                             f8(tt), f8(ct), name)\r
-                left_width = name_size + 1\r
-            else:\r
-                substats = '%s(%r) %s' % (name, value, f8(self.stats[func][3]))\r
-                left_width = name_size + 3\r
-            print >> self.stream, indent*left_width + substats\r
-            indent = " "\r
-\r
-    def print_title(self):\r
-        print >> self.stream, '   ncalls  tottime  percall  cumtime  percall',\r
-        print >> self.stream, 'filename:lineno(function)'\r
-\r
-    def print_line(self, func):  # hack : should print percentages\r
-        cc, nc, tt, ct, callers = self.stats[func]\r
-        c = str(nc)\r
-        if nc != cc:\r
-            c = c + '/' + str(cc)\r
-        print >> self.stream, c.rjust(9),\r
-        print >> self.stream, f8(tt),\r
-        if nc == 0:\r
-            print >> self.stream, ' '*8,\r
-        else:\r
-            print >> self.stream, f8(float(tt)/nc),\r
-        print >> self.stream, f8(ct),\r
-        if cc == 0:\r
-            print >> self.stream, ' '*8,\r
-        else:\r
-            print >> self.stream, f8(float(ct)/cc),\r
-        print >> self.stream, func_std_string(func)\r
-\r
-class TupleComp:\r
-    """This class provides a generic function for comparing any two tuples.\r
-    Each instance records a list of tuple-indices (from most significant\r
-    to least significant), and sort direction (ascending or decending) for\r
-    each tuple-index.  The compare functions can then be used as the function\r
-    argument to the system sort() function when a list of tuples need to be\r
-    sorted in the instances order."""\r
-\r
-    def __init__(self, comp_select_list):\r
-        self.comp_select_list = comp_select_list\r
-\r
-    def compare (self, left, right):\r
-        for index, direction in self.comp_select_list:\r
-            l = left[index]\r
-            r = right[index]\r
-            if l < r:\r
-                return -direction\r
-            if l > r:\r
-                return direction\r
-        return 0\r
-\r
-#**************************************************************************\r
-# func_name is a triple (file:string, line:int, name:string)\r
-\r
-def func_strip_path(func_name):\r
-    filename, line, name = func_name\r
-    return os.path.basename(filename), line, name\r
-\r
-def func_get_function_name(func):\r
-    return func[2]\r
-\r
-def func_std_string(func_name): # match what old profile produced\r
-    if func_name[:2] == ('~', 0):\r
-        # special case for built-in functions\r
-        name = func_name[2]\r
-        if name.startswith('<') and name.endswith('>'):\r
-            return '{%s}' % name[1:-1]\r
-        else:\r
-            return name\r
-    else:\r
-        return "%s:%d(%s)" % func_name\r
-\r
-#**************************************************************************\r
-# The following functions combine statists for pairs functions.\r
-# The bulk of the processing involves correctly handling "call" lists,\r
-# such as callers and callees.\r
-#**************************************************************************\r
-\r
-def add_func_stats(target, source):\r
-    """Add together all the stats for two profile entries."""\r
-    cc, nc, tt, ct, callers = source\r
-    t_cc, t_nc, t_tt, t_ct, t_callers = target\r
-    return (cc+t_cc, nc+t_nc, tt+t_tt, ct+t_ct,\r
-              add_callers(t_callers, callers))\r
-\r
-def add_callers(target, source):\r
-    """Combine two caller lists in a single list."""\r
-    new_callers = {}\r
-    for func, caller in target.iteritems():\r
-        new_callers[func] = caller\r
-    for func, caller in source.iteritems():\r
-        if func in new_callers:\r
-            if isinstance(caller, tuple):\r
-                # format used by cProfile\r
-                new_callers[func] = tuple([i[0] + i[1] for i in\r
-                                           zip(caller, new_callers[func])])\r
-            else:\r
-                # format used by profile\r
-                new_callers[func] += caller\r
-        else:\r
-            new_callers[func] = caller\r
-    return new_callers\r
-\r
-def count_calls(callers):\r
-    """Sum the caller statistics to get total number of calls received."""\r
-    nc = 0\r
-    for calls in callers.itervalues():\r
-        nc += calls\r
-    return nc\r
-\r
-#**************************************************************************\r
-# The following functions support printing of reports\r
-#**************************************************************************\r
-\r
-def f8(x):\r
-    return "%8.3f" % x\r
-\r
-#**************************************************************************\r
-# Statistics browser added by ESR, April 2001\r
-#**************************************************************************\r
-\r
-if __name__ == '__main__':\r
-    import cmd\r
-    try:\r
-        import readline\r
-    except ImportError:\r
-        pass\r
-\r
-    class ProfileBrowser(cmd.Cmd):\r
-        def __init__(self, profile=None):\r
-            cmd.Cmd.__init__(self)\r
-            self.prompt = "% "\r
-            self.stats = None\r
-            self.stream = sys.stdout\r
-            if profile is not None:\r
-                self.do_read(profile)\r
-\r
-        def generic(self, fn, line):\r
-            args = line.split()\r
-            processed = []\r
-            for term in args:\r
-                try:\r
-                    processed.append(int(term))\r
-                    continue\r
-                except ValueError:\r
-                    pass\r
-                try:\r
-                    frac = float(term)\r
-                    if frac > 1 or frac < 0:\r
-                        print >> self.stream, "Fraction argument must be in [0, 1]"\r
-                        continue\r
-                    processed.append(frac)\r
-                    continue\r
-                except ValueError:\r
-                    pass\r
-                processed.append(term)\r
-            if self.stats:\r
-                getattr(self.stats, fn)(*processed)\r
-            else:\r
-                print >> self.stream, "No statistics object is loaded."\r
-            return 0\r
-        def generic_help(self):\r
-            print >> self.stream, "Arguments may be:"\r
-            print >> self.stream, "* An integer maximum number of entries to print."\r
-            print >> self.stream, "* A decimal fractional number between 0 and 1, controlling"\r
-            print >> self.stream, "  what fraction of selected entries to print."\r
-            print >> self.stream, "* A regular expression; only entries with function names"\r
-            print >> self.stream, "  that match it are printed."\r
-\r
-        def do_add(self, line):\r
-            if self.stats:\r
-                self.stats.add(line)\r
-            else:\r
-                print >> self.stream, "No statistics object is loaded."\r
-            return 0\r
-        def help_add(self):\r
-            print >> self.stream, "Add profile info from given file to current statistics object."\r
-\r
-        def do_callees(self, line):\r
-            return self.generic('print_callees', line)\r
-        def help_callees(self):\r
-            print >> self.stream, "Print callees statistics from the current stat object."\r
-            self.generic_help()\r
-\r
-        def do_callers(self, line):\r
-            return self.generic('print_callers', line)\r
-        def help_callers(self):\r
-            print >> self.stream, "Print callers statistics from the current stat object."\r
-            self.generic_help()\r
-\r
-        def do_EOF(self, line):\r
-            print >> self.stream, ""\r
-            return 1\r
-        def help_EOF(self):\r
-            print >> self.stream, "Leave the profile brower."\r
-\r
-        def do_quit(self, line):\r
-            return 1\r
-        def help_quit(self):\r
-            print >> self.stream, "Leave the profile brower."\r
-\r
-        def do_read(self, line):\r
-            if line:\r
-                try:\r
-                    self.stats = Stats(line)\r
-                except IOError, args:\r
-                    print >> self.stream, args[1]\r
-                    return\r
-                except Exception as err:\r
-                    print >> self.stream, err.__class__.__name__ + ':', err\r
-                    return\r
-                self.prompt = line + "% "\r
-            elif len(self.prompt) > 2:\r
-                line = self.prompt[:-2]\r
-                self.do_read(line)\r
-            else:\r
-                print >> self.stream, "No statistics object is current -- cannot reload."\r
-            return 0\r
-        def help_read(self):\r
-            print >> self.stream, "Read in profile data from a specified file."\r
-            print >> self.stream, "Without argument, reload the current file."\r
-\r
-        def do_reverse(self, line):\r
-            if self.stats:\r
-                self.stats.reverse_order()\r
-            else:\r
-                print >> self.stream, "No statistics object is loaded."\r
-            return 0\r
-        def help_reverse(self):\r
-            print >> self.stream, "Reverse the sort order of the profiling report."\r
-\r
-        def do_sort(self, line):\r
-            if not self.stats:\r
-                print >> self.stream, "No statistics object is loaded."\r
-                return\r
-            abbrevs = self.stats.get_sort_arg_defs()\r
-            if line and all((x in abbrevs) for x in line.split()):\r
-                self.stats.sort_stats(*line.split())\r
-            else:\r
-                print >> self.stream, "Valid sort keys (unique prefixes are accepted):"\r
-                for (key, value) in Stats.sort_arg_dict_default.iteritems():\r
-                    print >> self.stream, "%s -- %s" % (key, value[1])\r
-            return 0\r
-        def help_sort(self):\r
-            print >> self.stream, "Sort profile data according to specified keys."\r
-            print >> self.stream, "(Typing `sort' without arguments lists valid keys.)"\r
-        def complete_sort(self, text, *args):\r
-            return [a for a in Stats.sort_arg_dict_default if a.startswith(text)]\r
-\r
-        def do_stats(self, line):\r
-            return self.generic('print_stats', line)\r
-        def help_stats(self):\r
-            print >> self.stream, "Print statistics from the current stat object."\r
-            self.generic_help()\r
-\r
-        def do_strip(self, line):\r
-            if self.stats:\r
-                self.stats.strip_dirs()\r
-            else:\r
-                print >> self.stream, "No statistics object is loaded."\r
-        def help_strip(self):\r
-            print >> self.stream, "Strip leading path information from filenames in the report."\r
-\r
-        def help_help(self):\r
-            print >> self.stream, "Show help for a given command."\r
-\r
-        def postcmd(self, stop, line):\r
-            if stop:\r
-                return stop\r
-            return None\r
-\r
-    import sys\r
-    if len(sys.argv) > 1:\r
-        initprofile = sys.argv[1]\r
-    else:\r
-        initprofile = None\r
-    try:\r
-        browser = ProfileBrowser(initprofile)\r
-        print >> browser.stream, "Welcome to the profile statistics browser."\r
-        browser.cmdloop()\r
-        print >> browser.stream, "Goodbye."\r
-    except KeyboardInterrupt:\r
-        pass\r
-\r
-# That's all, folks.\r