#!/usr/bin/env python

# portions copyright 2001, Autonomous Zones Industries, Inc., all rights...
# err...  reserved and offered to the public under the terms of the
# Python 2.2 license.
# Author: Zooko O'Whielacronx
# http://zooko.com/
# mailto:zooko@zooko.com
#
# Copyright 2000, Mojam Media, Inc., all rights reserved.
# Author: Skip Montanaro
#
# Copyright 1999, Bioreason, Inc., all rights reserved.
# Author: Andrew Dalke
#
# Copyright 1995-1997, Automatrix, Inc., all rights reserved.
# Author: Skip Montanaro
#
# Copyright 1991-1995, Stichting Mathematisch Centrum, all rights reserved.
#
#
# Permission to use, copy, modify, and distribute this Python software and
# its associated documentation for any purpose without fee is hereby
# granted, provided that the above copyright notice appears in all copies,
# and that both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of neither Automatrix,
# Bioreason or Mojam Media be used in advertising or publicity pertaining to
# distribution of the software without specific, written prior permission.
#
"""program/module to trace Python program or function execution

Sample use, command line:
  trace.py -c -f counts --ignore-dir '$prefix' spam.py eggs
  trace.py -t --ignore-dir '$prefix' spam.py eggs

Sample use, programmatically
   # create a Trace object, telling it what to ignore, and whether to
   # do tracing or line-counting or both.
   trace = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix,], trace=0,
                       count=1)
   # run the new command using the given trace
   trace.run(coverage.globaltrace, 'main()')
   # make a report, telling it where you want output
   r = trace.results()
   r.write_results(show_missing=1)
"""

import sys, os, tempfile, types, copy, operator, inspect, exceptions, marshal
try:
    import cPickle
    pickle = cPickle
except ImportError:
    import pickle

# DEBUG_MODE=1  # make this true to get printouts which help you understand what's going on

def usage(outfile):
    outfile.write("""Usage: %s [OPTIONS] <file> [ARGS]

Meta-options:
--help                Display this help then exit.
--version             Output version information then exit.

Otherwise, exactly one of the following three options must be given:
-t, --trace           Print each line to sys.stdout before it is executed.
-c, --count           Count the number of times each line is executed
                      and write the counts to <module>.cover for each
                      module executed, in the module's directory.
                      See also `--coverdir', `--file', `--no-report' below.
-r, --report          Generate a report from a counts file; do not execute
                      any code.  `--file' must specify the results file to
                      read, which must have been created in a previous run
                      with `--count --file=FILE'.

Modifiers:
-f, --file=<file>     File to accumulate counts over several runs.
-R, --no-report       Do not generate the coverage report files.
                      Useful if you want to accumulate over several runs.
-C, --coverdir=<dir>  Directory where the report files.  The coverage
                      report for <package>.<module> is written to file
                      <dir>/<package>/<module>.cover.
-m, --missing         Annotate executable lines that were not executed
                      with '>>>>>> '.
-s, --summary         Write a brief summary on stdout for each file.
                      (Can only be used with --count or --report.)

Filters, may be repeated multiple times:
--ignore-module=<mod> Ignore the given module and its submodules
                      (if it is a package).
--ignore-dir=<dir>    Ignore files in the given directory (multiple
                      directories can be joined by os.pathsep).
""" % sys.argv[0])

class Ignore:
    def __init__(self, modules = None, dirs = None):
        self._mods = modules or []
        self._dirs = dirs or []

        self._dirs = map(os.path.normpath, self._dirs)
        self._ignore = { '<string>': 1 }

    def names(self, filename, modulename):
        if self._ignore.has_key(modulename):
            return self._ignore[modulename]

        # haven't seen this one before, so see if the module name is
        # on the ignore list.  Need to take some care since ignoring
        # "cmp" musn't mean ignoring "cmpcache" but ignoring
        # "Spam" must also mean ignoring "Spam.Eggs".
        for mod in self._mods:
            if mod == modulename:  # Identical names, so ignore
                self._ignore[modulename] = 1
                return 1
            # check if the module is a proper submodule of something on
            # the ignore list
            n = len(mod)
            # (will not overflow since if the first n characters are the
            # same and the name has not already occured, then the size
            # of "name" is greater than that of "mod")
            if mod == modulename[:n] and modulename[n] == '.':
                self._ignore[modulename] = 1
                return 1

        # Now check that __file__ isn't in one of the directories
        if filename is None:
            # must be a built-in, so we must ignore
            self._ignore[modulename] = 1
            return 1

        # Ignore a file when it contains one of the ignorable paths
        for d in self._dirs:
            # The '+ os.sep' is to ensure that d is a parent directory,
            # as compared to cases like:
            #  d = "/usr/local"
            #  filename = "/usr/local.py"
            # or
            #  d = "/usr/local.py"
            #  filename = "/usr/local.py"
            if filename.startswith(d + os.sep):
                self._ignore[modulename] = 1
                return 1

        # Tried the different ways, so we don't ignore this module
        self._ignore[modulename] = 0
        return 0

class CoverageResults:
    def __init__(self, counts=None, calledfuncs=None, infile=None,
                 outfile=None):
        self.counts = counts
        if self.counts is None:
            self.counts = {}
        self.counter = self.counts.copy() # map (filename, lineno) to count
        self.calledfuncs = calledfuncs
        if self.calledfuncs is None:
            self.calledfuncs = {}
        self.calledfuncs = self.calledfuncs.copy()
        self.infile = infile
        self.outfile = outfile
        if self.infile:
            # try and merge existing counts file
            try:
                thingie = pickle.load(open(self.infile, 'r'))
                if type(thingie) is types.DictType:
                    # backwards compatibility for old trace.py after
                    # Zooko touched it but before calledfuncs  --Zooko
                    # 2001-10-24
                    self.update(self.__class__(thingie))
                elif type(thingie) is types.TupleType and len(thingie) == 2:
                    counts, calledfuncs = thingie
                    self.update(self.__class__(counts, calledfuncs))
            except (IOError, EOFError):
                pass
            except pickle.UnpicklingError:
                # backwards compatibility for old trace.py before
                # Zooko touched it  --Zooko 2001-10-24
                self.update(self.__class__(marshal.load(open(self.infile))))

    def update(self, other):
        """Merge in the data from another CoverageResults"""
        counts = self.counts
        calledfuncs = self.calledfuncs
        other_counts = other.counts
        other_calledfuncs = other.calledfuncs

        for key in other_counts.keys():
            if key != 'calledfuncs':
                # backwards compatibility for abortive attempt to
                # stuff calledfuncs into self.counts, by Zooko
                # --Zooko 2001-10-24
                counts[key] = counts.get(key, 0) + other_counts[key]

        for key in other_calledfuncs.keys():
            calledfuncs[key] = 1

    def write_results(self, show_missing = 1, summary = 0, coverdir = None):
        """
        @param coverdir
        """
        for filename, modulename, funcname in self.calledfuncs.keys():
            print ("filename: %s, modulename: %s, funcname: %s"
                   % (filename, modulename, funcname))

        import re
        # turn the counts data ("(filename, lineno) = count") into something
        # accessible on a per-file basis
        per_file = {}
        for thingie in self.counts.keys():
            if thingie != "calledfuncs":
                # backwards compatibility for abortive attempt to
                # stuff calledfuncs into self.counts, by Zooko --Zooko
                # 2001-10-24
                filename, lineno = thingie
                lines_hit = per_file[filename] = per_file.get(filename, {})
                lines_hit[lineno] = self.counts[(filename, lineno)]

        # there are many places where this is insufficient, like a blank
        # line embedded in a multiline string.
        blank = re.compile(r'^\s*(#.*)?$')

        # accumulate summary info, if needed
        sums = {}

        # generate file paths for the coverage files we are going to write...
        fnlist = []
        tfdir = tempfile.gettempdir()
        for key in per_file.keys():
            filename = key

            # skip some "files" we don't care about...
            if filename == "<string>":
                continue
            # are these caused by code compiled using exec or something?
            if filename.startswith(tfdir):
                continue

            modulename = inspect.getmodulename(filename)

            if filename.endswith(".pyc") or filename.endswith(".pyo"):
                filename = filename[:-1]

            if coverdir:
                thiscoverdir = coverdir
            else:
                thiscoverdir = os.path.dirname(os.path.abspath(filename))

            # the code from here to "<<<" is the contents of the `fileutil.make_dirs()' function in the Mojo Nation project.  --Zooko 2001-10-14
            # http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/mojonation/evil/common/fileutil.py?rev=HEAD&content-type=text/vnd.viewcvs-markup
            tx = None
            try:
                os.makedirs(thiscoverdir)
            except OSError, x:
                tx = x

            if not os.path.isdir(thiscoverdir):
                if tx:
                    raise tx
                raise exceptions.IOError, "unknown error prevented creation of directory: %s" % thiscoverdir # careful not to construct an IOError with a 2-tuple, as that has a special meaning...
            # <<<

            # build list file name by appending a ".cover" to the module name
            # and sticking it into the specified directory
            if "." in modulename:
                # A module in a package
                finalname = modulename.split(".")[-1]
                listfilename = os.path.join(thiscoverdir, finalname + ".cover")
            else:
                listfilename = os.path.join(thiscoverdir, modulename + ".cover")

            # Get the original lines from the .py file
            try:
                lines = open(filename, 'r').readlines()
            except IOError, err:
                sys.stderr.write("trace: Could not open %s for reading because: %s - skipping\n" % (`filename`, err))
                continue

            try:
                outfile = open(listfilename, 'w')
            except IOError, err:
                sys.stderr.write(
                    '%s: Could not open %s for writing because: %s" \
                    "- skipping\n' % ("trace", `listfilename`, err))
                continue

            # If desired, get a list of the line numbers which represent
            # executable content (returned as a dict for better lookup speed)
            if show_missing:
                executable_linenos = find_executable_linenos(filename)
            else:
                executable_linenos = {}

            n_lines = 0
            n_hits = 0
            lines_hit = per_file[key]
            for i in range(len(lines)):
                line = lines[i]

                # do the blank/comment match to try to mark more lines
                # (help the reader find stuff that hasn't been covered)
                if lines_hit.has_key(i+1):
                    # count precedes the lines that we captured
                    outfile.write('%5d: ' % lines_hit[i+1])
                    n_hits = n_hits + 1
                    n_lines = n_lines + 1
                elif blank.match(line):
                    # blank lines and comments are preceded by dots
                    outfile.write('    . ')
                else:
                    # lines preceded by no marks weren't hit
                    # Highlight them if so indicated, unless the line contains
                    # '#pragma: NO COVER' (it is possible to embed this into
                    # the text as a non-comment; no easy fix)
                    if executable_linenos.has_key(i+1) and \
                       lines[i].find(' '.join(['#pragma', 'NO COVER'])) == -1:
                        outfile.write('>>>>>> ')
                    else:
                        outfile.write(' '*7)
                    n_lines = n_lines + 1
                outfile.write(lines[i].expandtabs(8))

            outfile.close()

            if summary and n_lines:
                percent = int(100 * n_hits / n_lines)
                sums[modulename] = n_lines, percent, modulename, filename

        if summary and sums:
            mods = sums.keys()
            mods.sort()
            print "lines   cov%   module   (path)"
            for m in mods:
                n_lines, percent, modulename, filename = sums[m]
                print "%5d   %3d%%   %s   (%s)" % sums[m]

        if self.outfile:
            # try and store counts and module info into self.outfile
            try:
                pickle.dump((self.counts, self.calledfuncs),
                            open(self.outfile, 'w'), 1)
            except IOError, err:
                sys.stderr.write("cannot save counts files because %s" % err)

def _find_LINENO_from_code(code):
    """return the numbers of the lines containing the source code that
    was compiled into code"""
    linenos = {}

    line_increments = [ord(c) for c in code.co_lnotab[1::2]]
    table_length = len(line_increments)

    lineno = code.co_firstlineno

    for li in line_increments:
        linenos[lineno] = 1
        lineno += li
    linenos[lineno] = 1

    return linenos

def _find_LINENO(code):
    """return all of the lineno information from a code object"""
    import types

    # get all of the lineno information from the code of this scope level
    linenos = _find_LINENO_from_code(code)

    # and check the constants for references to other code objects
    for c in code.co_consts:
        if type(c) == types.CodeType:
            # find another code object, so recurse into it
            linenos.update(_find_LINENO(c))
    return linenos

def find_executable_linenos(filename):
    """return a dict of the line numbers from executable statements in a file

    """
    import parser

    assert filename.endswith('.py')

    prog = open(filename).read()
    ast = parser.suite(prog)
    code = parser.compileast(ast, filename)

    return _find_LINENO(code)

### XXX because os.path.commonprefix seems broken by my way of thinking...
def commonprefix(dirs):
    "Given a list of pathnames, returns the longest common leading component"
    if not dirs: return ''
    n = copy.copy(dirs)
    for i in range(len(n)):
        n[i] = n[i].split(os.sep)
    prefix = n[0]
    for item in n:
        for i in range(len(prefix)):
            if prefix[:i+1] <> item[:i+1]:
                prefix = prefix[:i]
                if i == 0: return ''
                break
    return os.sep.join(prefix)

class Trace:
    def __init__(self, count=1, trace=1, countfuncs=0, ignoremods=(),
                 ignoredirs=(), infile=None, outfile=None):
        """
        @param count true iff it should count number of times each
                     line is executed
        @param trace true iff it should print out each line that is
                     being counted
        @param countfuncs true iff it should just output a list of
                     (filename, modulename, funcname,) for functions
                     that were called at least once;  This overrides
                     `count' and `trace'
        @param ignoremods a list of the names of modules to ignore
        @param ignoredirs a list of the names of directories to ignore
                     all of the (recursive) contents of
        @param infile file from which to read stored counts to be
                     added into the results
        @param outfile file in which to write the results
        """
        self.infile = infile
        self.outfile = outfile
        self.ignore = Ignore(ignoremods, ignoredirs)
        self.counts = {}   # keys are (filename, linenumber)
        self.blabbed = {} # for debugging
        self.pathtobasename = {} # for memoizing os.path.basename
        self.donothing = 0
        self.trace = trace
        self._calledfuncs = {}
        if countfuncs:
            self.globaltrace = self.globaltrace_countfuncs
        elif trace and count:
            self.globaltrace = self.globaltrace_lt
            self.localtrace = self.localtrace_trace_and_count
        elif trace:
            self.globaltrace = self.globaltrace_lt
            self.localtrace = self.localtrace_trace
        elif count:
            self.globaltrace = self.globaltrace_lt
            self.localtrace = self.localtrace_count
        else:
            # Ahem -- do nothing?  Okay.
            self.donothing = 1

    def run(self, cmd):
        import __main__
        dict = __main__.__dict__
        if not self.donothing:
            sys.settrace(self.globaltrace)
        try:
            exec cmd in dict, dict
        finally:
            if not self.donothing:
                sys.settrace(None)

    def runctx(self, cmd, globals=None, locals=None):
        if globals is None: globals = {}
        if locals is None: locals = {}
        if not self.donothing:
            sys.settrace(self.globaltrace)
        try:
            exec cmd in globals, locals
        finally:
            if not self.donothing:
                sys.settrace(None)

    def runfunc(self, func, *args, **kw):
        result = None
        if not self.donothing:
            sys.settrace(self.globaltrace)
        try:
            result = apply(func, args, kw)
        finally:
            if not self.donothing:
                sys.settrace(None)
        return result

    def globaltrace_countfuncs(self, frame, why, arg):
        """
        Handles `call' events (why == 'call') and adds the (filename, modulename, funcname,) to the self._calledfuncs dict.
        """
        if why == 'call':
            filename, lineno, funcname, context, lineindex = \
                      inspect.getframeinfo(frame, 0)
            if filename:
                modulename = inspect.getmodulename(filename)
            else:
                modulename = None
            self._calledfuncs[(filename, modulename, funcname,)] = 1

    def globaltrace_lt(self, frame, why, arg):
        """
        Handles `call' events (why == 'call') and if the code block being entered is to be ignored then it returns `None', else it returns `self.localtrace'.
        """
        if why == 'call':
            filename, lineno, funcname, context, lineindex = \
                      inspect.getframeinfo(frame, 0)
            if filename:
                modulename = inspect.getmodulename(filename)
                if modulename is not None:
                    ignore_it = self.ignore.names(filename, modulename)
                    if not ignore_it:
                        if self.trace:
                            print (" --- modulename: %s, funcname: %s"
                                   % (modulename, funcname))
                        return self.localtrace
            else:
                # XXX why no filename?
                return None

    def localtrace_trace_and_count(self, frame, why, arg):
        if why == 'line':
            # record the file name and line number of every trace
            # XXX I wish inspect offered me an optimized
            # `getfilename(frame)' to use in place of the presumably
            # heavier `getframeinfo()'.  --Zooko 2001-10-14

            filename, lineno, funcname, context, lineindex = \
                      inspect.getframeinfo(frame, 1)
            key = filename, lineno
            self.counts[key] = self.counts.get(key, 0) + 1

            # XXX not convinced that this memoizing is a performance
            # win -- I don't know enough about Python guts to tell.
            # --Zooko 2001-10-14

            bname = self.pathtobasename.get(filename)
            if bname is None:

                # Using setdefault faster than two separate lines?
                # --Zooko 2001-10-14
                bname = self.pathtobasename.setdefault(filename,
                                       os.path.basename(filename))
            try:
                print "%s(%d): %s" % (bname, lineno, context[lineindex]),
            except IndexError:
                # Uh.. sometimes getframeinfo gives me a context of
                # length 1 and a lineindex of -2.  Oh well.
                pass
        return self.localtrace

    def localtrace_trace(self, frame, why, arg):
        if why == 'line':
            # XXX shouldn't do the count increment when arg is
            # exception?  But be careful to return self.localtrace
            # when arg is exception! ?  --Zooko 2001-10-14

            # record the file name and line number of every trace XXX
            # I wish inspect offered me an optimized
            # `getfilename(frame)' to use in place of the presumably
            # heavier `getframeinfo()'.  --Zooko 2001-10-14
            filename, lineno, funcname, context, lineindex = \
                      inspect.getframeinfo(frame)

            # XXX not convinced that this memoizing is a performance
            # win -- I don't know enough about Python guts to tell.
            # --Zooko 2001-10-14
            bname = self.pathtobasename.get(filename)
            if bname is None:
                # Using setdefault faster than two separate lines?
                # --Zooko 2001-10-14
                bname = self.pathtobasename.setdefault(filename, os.path.basename(filename))
            if context is not None:
                try:
                    print "%s(%d): %s" % (bname, lineno, context[lineindex]),
                except IndexError:
                    # Uh.. sometimes getframeinfo gives me a context of length 1 and a lineindex of -2.  Oh well.
                    pass
            else:
                print "%s(???): ???" % bname
        return self.localtrace

    def localtrace_count(self, frame, why, arg):
        if why == 'line':
            filename = frame.f_code.co_filename
            lineno = frame.f_lineno
            key = filename, lineno
            self.counts[key] = self.counts.get(key, 0) + 1
        return self.localtrace

    def results(self):
        return CoverageResults(self.counts, infile=self.infile,
                               outfile=self.outfile,
                               calledfuncs=self._calledfuncs)

def _err_exit(msg):
    sys.stderr.write("%s: %s\n" % (sys.argv[0], msg))
    sys.exit(1)

def main(argv=None):
    import getopt

    if argv is None:
        argv = sys.argv
    try:
        opts, prog_argv = getopt.getopt(argv[1:], "tcrRf:d:msC:l",
                                        ["help", "version", "trace", "count",
                                         "report", "no-report", "summary",
                                         "file=", "missing",
                                         "ignore-module=", "ignore-dir=",
                                         "coverdir=", "listfuncs",])

    except getopt.error, msg:
        sys.stderr.write("%s: %s\n" % (sys.argv[0], msg))
        sys.stderr.write("Try `%s --help' for more information\n"
                         % sys.argv[0])
        sys.exit(1)

    trace = 0
    count = 0
    report = 0
    no_report = 0
    counts_file = None
    missing = 0
    ignore_modules = []
    ignore_dirs = []
    coverdir = None
    summary = 0
    listfuncs = False

    for opt, val in opts:
        if opt == "--help":
            usage(sys.stdout)
            sys.exit(0)

        if opt == "--version":
            sys.stdout.write("trace 2.0\n")
            sys.exit(0)

        if opt == "-l" or opt == "--listfuncs":
            listfuncs = True
            continue

        if opt == "-t" or opt == "--trace":
            trace = 1
            continue

        if opt == "-c" or opt == "--count":
            count = 1
            continue

        if opt == "-r" or opt == "--report":
            report = 1
            continue

        if opt == "-R" or opt == "--no-report":
            no_report = 1
            continue

        if opt == "-f" or opt == "--file":
            counts_file = val
            continue

        if opt == "-m" or opt == "--missing":
            missing = 1
            continue

        if opt == "-C" or opt == "--coverdir":
            coverdir = val
            continue

        if opt == "-s" or opt == "--summary":
            summary = 1
            continue

        if opt == "--ignore-module":
            ignore_modules.append(val)
            continue

        if opt == "--ignore-dir":
            for s in val.split(os.pathsep):
                s = os.path.expandvars(s)
                # should I also call expanduser? (after all, could use $HOME)

                s = s.replace("$prefix",
                              os.path.join(sys.prefix, "lib",
                                           "python" + sys.version[:3]))
                s = s.replace("$exec_prefix",
                              os.path.join(sys.exec_prefix, "lib",
                                           "python" + sys.version[:3]))
                s = os.path.normpath(s)
                ignore_dirs.append(s)
            continue

        assert 0, "Should never get here"

    if listfuncs and (count or trace):
        _err_exit("cannot specify both --listfuncs and (--trace or --count)")

    if not count and not trace and not report and not listfuncs:
        _err_exit("must specify one of --trace, --count, --report or --listfuncs")

    if report and no_report:
        _err_exit("cannot specify both --report and --no-report")

    if report and not counts_file:
        _err_exit("--report requires a --file")

    if no_report and len(prog_argv) == 0:
        _err_exit("missing name of file to run")

    # everything is ready
    if report:
        results = CoverageResults(infile=counts_file, outfile=counts_file)
        results.write_results(missing, summary=summary, coverdir=coverdir)
    else:
        sys.argv = prog_argv
        progname = prog_argv[0]
        sys.path[0] = os.path.split(progname)[0]

        t = Trace(count, trace, countfuncs=listfuncs,
                  ignoremods=ignore_modules, ignoredirs=ignore_dirs,
                  infile=counts_file, outfile=counts_file)
        try:
            t.run('execfile(' + `progname` + ')')
        except IOError, err:
            _err_exit("Cannot run file %s because: %s" % (`sys.argv[0]`, err))
        except SystemExit:
            pass

        results = t.results()

        if not no_report:
            results.write_results(missing, summary=summary, coverdir=coverdir)

if __name__=='__main__':
    main()
