"""Class for printing reports on profiled python code."""

# Class for printing reports on profiled python code. rev 1.0  4/1/94
#
# Based on prior profile module by Sjoerd Mullender...
#   which was hacked somewhat by: Guido van Rossum
#
# see profile.doc and profile.py for more info.

# Copyright 1994, by InfoSeek Corporation, all rights reserved.
# Written by James Roskind
# 
# Permission to use, copy, modify, and distribute this Python software
# and its associated documentation for any purpose (subject to the
# restriction in the following sentence) 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 InfoSeek not be used in
# advertising or publicity pertaining to distribution of the software
# without specific, written prior permission.  This permission is
# explicitly restricted to the copying and modification of the software
# to remain in Python, compiled Python, or other languages (such as C)
# wherein the modified or derived code is exclusively imported into a
# Python module.
# 
# INFOSEEK CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
# FITNESS. IN NO EVENT SHALL INFOSEEK CORPORATION BE LIABLE FOR ANY
# SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.


import os
import time
import string
import marshal
import re

import fpformat

class Stats:
	"""This class is used for creating reports from data generated by the
	Profile class.  It is a "friend" of that class, and imports data either
	by direct access to members of Profile class, or by reading in a dictionary
	that was emitted (via marshal) from the Profile class.

	The big change from the previous Profiler (in terms of raw functionality)
	is that an "add()" method has been provided to combine Stats from
	several distinct profile runs.  Both the constructor and the add()
	method now take arbitrarilly many file names as arguments.

	All the print methods now take an argument that indicats how many lines
	to print.  If the arg is a floating point number between 0 and 1.0, then
	it is taken as a decimal percentage of the availabel lines to be printed
	(e.g., .1 means print 10% of all available lines).  If it is an integer,
	it is taken to mean the number of lines of data that you wish to have
	printed.

	The sort_stats() method now processes some additionaly options (i.e., in
	addition to the old -1, 0, 1, or 2).  It takes an arbitrary number of quoted
	strings to select the sort order.  For example sort_stats('time', 'name')
	sorts on the major key of "internal function time", and on the minor
	key of 'the name of the function'.  Look at the two tables in sort_stats()
	and get_sort_arg_defs(self) for more examples.

	All methods now return "self",  so you can string together commands like:
	    Stats('foo', 'goo').strip_dirs().sort_stats('calls').\
	                        print_stats(5).print_callers(5)
	"""
	
	def __init__(self, *args):
		if not len(args):
			arg = None
		else:
			arg = args[0]
			args = args[1:]
		self.init(arg)
		apply(self.add, args).ignore()
			
	def init(self, arg):
		self.all_callees = None  # calc only if needed
		self.files = []
		self.fcn_list = None
		self.total_tt = 0
		self.total_calls = 0
		self.prim_calls = 0
		self.max_name_len = 0
		self.top_level = {}
		self.stats = {}
		self.sort_arg_dict = {}
		self.load_stats(arg)
		trouble = 1
		try:
			self.get_top_level_stats()
			trouble = 0
		finally:
			if trouble:
				print "Invalid timing data",
				if self.files: print self.files[-1],
				print


	def load_stats(self, arg):
		if not arg:  self.stats = {}
		elif type(arg) == type(""):
			f = open(arg, 'rb')
			self.stats = marshal.load(f)
			f.close()
			try:
				file_stats = os.stat(arg)
				arg = time.ctime(file_stats[8]) + "    " + arg
			except:  # in case this is not unix
				pass
			self.files = [ arg ]
		elif hasattr(arg, 'create_stats'):
			arg.create_stats()
			self.stats = arg.stats
			arg.stats = {}
		if not self.stats:
			raise TypeError,  "Cannot create or construct a " \
				  + `self.__class__` \
				  + " object from '" + `arg` + "'"
		return

	def get_top_level_stats(self):
		for func in self.stats.keys():
			cc, nc, tt, ct, callers = self.stats[func]
			self.total_calls = self.total_calls + nc
			self.prim_calls  = self.prim_calls  + cc
			self.total_tt    = self.total_tt    + tt
			if callers.has_key(("jprofile", 0, "profiler")):
				self.top_level[func] = None
			if len(func_std_string(func)) > self.max_name_len:
				self.max_name_len = len(func_std_string(func))
					
	def add(self, *arg_list):
		if not arg_list: return self
		if len(arg_list) > 1: apply(self.add, arg_list[1:])
		other = arg_list[0]
		if type(self) != type(other) or \
			  self.__class__ != other.__class__:
			other = Stats(other)
		self.files = self.files + other.files
		self.total_calls = self.total_calls + other.total_calls
		self.prim_calls = self.prim_calls + other.prim_calls
		self.total_tt = self.total_tt + other.total_tt
		for func in other.top_level.keys():
			self.top_level[func] = None

		if self.max_name_len < other.max_name_len:
			self.max_name_len = other.max_name_len

		self.fcn_list = None

		for func in other.stats.keys():
			if self.stats.has_key(func):
				old_func_stat = self.stats[func]
			else:
				old_func_stat = (0, 0, 0, 0, {},)
			self.stats[func] = add_func_stats(old_func_stat, \
				  other.stats[func])
		return self
			


	# list the tuple indicies and directions for sorting,
	# along with some printable description
	sort_arg_dict_default = {\
		  "calls"     : (((1,-1),              ), "call count"),\
		  "cumulative": (((3,-1),              ), "cumulative time"),\
		  "file"      : (((4, 1),              ), "file name"),\
		  "line"      : (((5, 1),              ), "line number"),\
		  "module"    : (((4, 1),              ), "file name"),\
		  "name"      : (((6, 1),              ), "function name"),\
		  "nfl"       : (((6, 1),(4, 1),(5, 1),), "name/file/line"), \
		  "pcalls"    : (((0,-1),              ), "call count"),\
		  "stdname"   : (((7, 1),              ), "standard name"),\
		  "time"      : (((2,-1),              ), "internal time"),\
		  }

	def get_sort_arg_defs(self):
		"""Expand all abbreviations that are unique."""
		if not self.sort_arg_dict:
			self.sort_arg_dict = dict = {}
			std_list = dict.keys()
			bad_list = {}
			for word in self.sort_arg_dict_default.keys():
				fragment = word
				while fragment:
					if not fragment:
						break
					if dict.has_key(fragment):
						bad_list[fragment] = 0
						break
					dict[fragment] = self. \
						  sort_arg_dict_default[word]
					fragment = fragment[:-1]
			for word in bad_list.keys():
				del dict[word]
		return self.sort_arg_dict
			

	def sort_stats(self, *field):
		if not field:
			self.fcn_list = 0
			return self
		if len(field) == 1 and type(field[0]) == type(1):
			# Be compatible with old profiler
			field = [ {-1: "stdname", \
				  0:"calls", \
				  1:"time", \
				  2: "cumulative" }  [ field[0] ] ]

		sort_arg_defs = self.get_sort_arg_defs()
		sort_tuple = ()
		self.sort_type = ""
		connector = ""
		for word in field:
			sort_tuple = sort_tuple + sort_arg_defs[word][0]
			self.sort_type = self.sort_type + connector + \
				  sort_arg_defs[word][1]
			connector = ", "
					
		stats_list = []
		for func in self.stats.keys():
			cc, nc, tt, ct, callers = self.stats[func]
			stats_list.append((cc, nc, tt, ct) + func_split(func) \
				           + (func_std_string(func), func,)  )

		stats_list.sort(TupleComp(sort_tuple).compare)

		self.fcn_list = fcn_list = []
		for tuple in stats_list:
			fcn_list.append(tuple[-1])
		return self


	def reverse_order(self):
		if self.fcn_list: self.fcn_list.reverse()
		return self

	def strip_dirs(self):
		oldstats = self.stats
		self.stats = newstats = {}
		max_name_len = 0
		for func in oldstats.keys():
			cc, nc, tt, ct, callers = oldstats[func]
			newfunc = func_strip_path(func)
			if len(func_std_string(newfunc)) > max_name_len:
				max_name_len = len(func_std_string(newfunc))
			newcallers = {}
			for func2 in callers.keys():
				newcallers[func_strip_path(func2)] = \
					  callers[func2]

			if newstats.has_key(newfunc):
				newstats[newfunc] = add_func_stats( \
					  newstats[newfunc],\
					  (cc, nc, tt, ct, newcallers))
			else:
				newstats[newfunc] = (cc, nc, tt, ct, newcallers)
		old_top = self.top_level
		self.top_level = new_top = {}
		for func in old_top.keys():
			new_top[func_strip_path(func)] = None

		self.max_name_len = max_name_len

		self.fcn_list = None
		self.all_callees = None
		return self



	def calc_callees(self):
		if self.all_callees: return
		self.all_callees = all_callees = {}
		for func in self.stats.keys():
			if not all_callees.has_key(func):
				all_callees[func] = {}
			cc, nc, tt, ct, callers = self.stats[func]
			for func2 in callers.keys():
				if not all_callees.has_key(func2):
					all_callees[func2] = {}
				all_callees[func2][func]  = callers[func2]
		return

	#******************************************************************
	# The following functions support actual printing of reports
	#******************************************************************

	# Optional "amount" is either a line count, or a percentage of lines.

	def eval_print_amount(self, sel, list, msg):
		new_list = list
		if type(sel) == type(""):
			new_list = []
			for func in list:
				if re.search(sel, func_std_string(func)):
					new_list.append(func)
		else:
			count = len(list)
			if type(sel) == type(1.0) and 0.0 <= sel < 1.0:
				count = int (count * sel + .5)
				new_list = list[:count]
			elif type(sel) == type(1) and 0 <= sel < count:
				count = sel
				new_list = list[:count]
		if len(list) != len(new_list):
			msg = msg + "   List reduced from " + `len(list)` \
				  + " to " + `len(new_list)` + \
				  " due to restriction <" + `sel` + ">\n"
			
		return new_list, msg



	def get_print_list(self, sel_list):
		width = self.max_name_len
		if self.fcn_list:
			list = self.fcn_list[:]
			msg = "   Ordered by: " + self.sort_type + '\n'
		else:
			list = self.stats.keys()
			msg = "   Random listing order was used\n"

		for selection in sel_list:
			list,msg = self.eval_print_amount(selection, list, msg)

		count = len(list)

		if not list:
			return 0, list
		print msg
		if count < len(self.stats):
			width = 0
			for func in list:
				if  len(func_std_string(func)) > width:
					width = len(func_std_string(func))
		return width+2, list
		
	def print_stats(self, *amount):
		for filename in self.files:
			print filename
		if self.files: print
		indent = "        "
		for func in self.top_level.keys():
			print indent, func_get_function_name(func)
		
		print  indent, self.total_calls, "function calls",
		if self.total_calls != self.prim_calls:
			print "(" + `self.prim_calls`, "primitive calls)", 
		print "in", fpformat.fix(self.total_tt, 3), "CPU seconds"
		print
		width, list = self.get_print_list(amount)
		if list:
			self.print_title()
			for func in list:
				self.print_line(func)
			print 
			print
		return self

			
	def print_callees(self, *amount):
		width, list = self.get_print_list(amount)
		if list:
			self.calc_callees()

			self.print_call_heading(width, "called...")
			for func in list:
				if self.all_callees.has_key(func):
					self.print_call_line(width, \
						  func, self.all_callees[func])
				else:
					self.print_call_line(width, func, {})
			print
			print
		return self

	def print_callers(self, *amount):
		width, list = self.get_print_list(amount)
		if list:
			self.print_call_heading(width, "was called by...")
			for func in list:
				cc, nc, tt, ct, callers = self.stats[func]
				self.print_call_line(width, func, callers)
			print
			print
		return self

	def print_call_heading(self, name_size, column_title):
		print string.ljust("Function ", name_size) + column_title


	def print_call_line(self, name_size, source, call_dict):
		print string.ljust(func_std_string(source), name_size),
		if not call_dict:
			print "--"
			return
		clist = call_dict.keys()
		clist.sort()
		name_size = name_size + 1
		indent = ""
		for func in clist:
			name = func_std_string(func)
			print indent*name_size + name + '(' \
				  + `call_dict[func]`+')', \
				  f8(self.stats[func][3])
			indent = " "



	def print_title(self):
		print string.rjust('ncalls', 9),
		print string.rjust('tottime', 8),
		print string.rjust('percall', 8),
		print string.rjust('cumtime', 8),
		print string.rjust('percall', 8),
		print 'filename:lineno(function)'


	def print_line(self, func):  # hack : should print percentages
		cc, nc, tt, ct, callers = self.stats[func]
		c = `nc`
		if nc != cc:
			c = c + '/' + `cc`
		print string.rjust(c, 9),
		print f8(tt),
		if nc == 0:
			print ' '*8,
		else:
			print f8(tt/nc),
		print f8(ct),
		if cc == 0:
			print ' '*8,
		else:
			print f8(ct/cc),
		print func_std_string(func)


	def ignore(self):
		pass # has no return value, so use at end of line :-)


class TupleComp:
	"""This class provides a generic function for comparing any two tuples.
	Each instance records a list of tuple-indicies (from most significant
	to least significant), and sort direction (ascending or decending) for
	each tuple-index.  The compare functions can then be used as the function
	argument to the system sort() function when a list of tuples need to be
	sorted in the instances order."""

	def __init__(self, comp_select_list):
		self.comp_select_list = comp_select_list

	def compare (self, left, right):
		for index, direction in self.comp_select_list:
			l = left[index]
			r = right[index]
			if l < r:
				return -direction
			if l > r:
				return direction
		return 0

		

#**************************************************************************

def func_strip_path(func_name):
	file, line, name = func_name
	return os.path.basename(file), line, name

def func_get_function_name(func):
	return func[2]

def func_std_string(func_name): # match what old profile produced
	file, line, name = func_name
	return file + ":" + `line` + "(" + name + ")"

def func_split(func_name):
	return func_name

#**************************************************************************
# The following functions combine statists for pairs functions.
# The bulk of the processing involves correctly handling "call" lists,
# such as callers and callees. 
#**************************************************************************

def add_func_stats(target, source):
	"""Add together all the stats for two profile entries."""
	cc, nc, tt, ct, callers = source
	t_cc, t_nc, t_tt, t_ct, t_callers = target
	return (cc+t_cc, nc+t_nc, tt+t_tt, ct+t_ct, \
		  add_callers(t_callers, callers))


def add_callers(target, source):
	"""Combine two caller lists in a single list."""
	new_callers = {}
	for func in target.keys():
		new_callers[func] = target[func]
	for func in source.keys():
		if new_callers.has_key(func):
			new_callers[func] = source[func] + new_callers[func]
		else:
			new_callers[func] = source[func]
	return new_callers

def count_calls(callers):
	"""Sum the caller statistics to get total number of calls received."""
	nc = 0
	for func in callers.keys():
		nc = nc + callers[func]
	return nc

#**************************************************************************
# The following functions support printing of reports
#**************************************************************************

def f8(x):
	return string.rjust(fpformat.fix(x, 3), 8)

