#! /usr/bin/env python

# pdb.py -- finally, a Python debugger!

# (See pdb.doc for documentation.)

import string
import sys
import linecache
import cmd
import bdb
import repr
import os


# Interaction prompt line will separate file and call info from code
# text using value of line_prefix string.  A newline and arrow may
# be to your liking.  You can set it once pdb is imported using the
# command "pdb.line_prefix = '\n% '".
# line_prefix = ': '	# Use this to get the old situation back
line_prefix = '\n-> '	# Probably a better default

class Pdb(bdb.Bdb, cmd.Cmd):
	
	def __init__(self):
		bdb.Bdb.__init__(self)
		cmd.Cmd.__init__(self)
		self.prompt = '(Pdb) '
		self.lineinfoCmd = 'egrep -n "def *%s *[(:]" %s /dev/null'
		self.aliases = {}
		# Try to load readline if it exists
		try:
			import readline
		except ImportError:
			pass

		# Read $HOME/.pdbrc and ./.pdbrc
		self.rcLines = []
		if os.environ.has_key('HOME'):
			envHome = os.environ['HOME']
			try:
				rcFile = open (envHome + "/.pdbrc")
			except IOError:
				pass
			else:
				for line in rcFile.readlines():
					self.rcLines.append (line)
				rcFile.close()
		try:
			rcFile = open ("./.pdbrc")
		except IOError:
			pass
		else:
			for line in rcFile.readlines():
				self.rcLines.append (line)
			rcFile.close()
	
	def reset(self):
		bdb.Bdb.reset(self)
		self.forget()
	
	def forget(self):
		self.lineno = None
		self.stack = []
		self.curindex = 0
		self.curframe = None
	
	def setup(self, f, t):
		self.forget()
		self.stack, self.curindex = self.get_stack(f, t)
		self.curframe = self.stack[self.curindex][0]
		self.execRcLines()

	# Can be executed earlier than 'setup' if desired
	def execRcLines(self):
		if self.rcLines:
			# Make local copy because of recursion
			rcLines = self.rcLines
			# executed only once
			self.rcLines = []
			for line in rcLines:
				line = line[:-1]
				if len (line) > 0 and line[0] != '#':
					self.onecmd (line)
	
	# Override Bdb methods (except user_call, for now)
	
	def user_line(self, frame):
		# This function is called when we stop or break at this line
		self.interaction(frame, None)
	
	def user_return(self, frame, return_value):
		# This function is called when a return trap is set here
		frame.f_locals['__return__'] = return_value
		print '--Return--'
		self.interaction(frame, None)
	
	def user_exception(self, frame, (exc_type, exc_value, exc_traceback)):
		# This function is called if an exception occurs,
		# but only if we are to stop at or just below this level
		frame.f_locals['__exception__'] = exc_type, exc_value
		if type(exc_type) == type(''):
			exc_type_name = exc_type
		else: exc_type_name = exc_type.__name__
		print exc_type_name + ':', repr.repr(exc_value)
		self.interaction(frame, exc_traceback)
	
	# General interaction function
	
	def interaction(self, frame, traceback):
		self.setup(frame, traceback)
		self.print_stack_entry(self.stack[self.curindex])
		self.cmdloop()
		self.forget()

	def default(self, line):
		if line[:1] == '!': line = line[1:]
		locals = self.curframe.f_locals
		globals = self.curframe.f_globals
		try:
			code = compile(line + '\n', '<stdin>', 'single')
			exec code in globals, locals
		except:
			t, v = sys.exc_info()[:2]
			if type(t) == type(''):
				exc_type_name = t
			else: exc_type_name = t.__name__
			print '***', exc_type_name + ':', v

	def precmd(self, line):
		# Handle alias expansion and ';;' separator
		if not line:
			return line
		args = string.split(line)
		while self.aliases.has_key(args[0]):
			line = self.aliases[args[0]]
			ii = 1
			for tmpArg in args[1:]:
				line = string.replace(line, "%" + str(ii),
						      tmpArg)
				ii = ii + 1
			line = string.replace(line, "%*",
					      string.join(args[1:], ' '))
			args = string.split(line)
		# split into ';;' separated commands
		# unless it's an alias command
		if args[0] != 'alias':
			marker = string.find(line, ';;')
			if marker >= 0:
				# queue up everything after marker
				next = string.lstrip(line[marker+2:])
				self.cmdqueue.append(next)
				line = string.rstrip(line[:marker])
		return line

	# Command definitions, called by cmdloop()
	# The argument is the remaining string on the command line
	# Return true to exit from the command loop 
	
	do_h = cmd.Cmd.do_help

	def do_EOF(self, arg):
		return 0	# Don't die on EOF

	def do_break(self, arg, temporary = 0):
		# break [ ([filename:]lineno | function) [, "condition"] ]
		if not arg:
			if self.breaks:  # There's at least one
				print "Num Type         Disp Enb   Where"
				for bp in bdb.Breakpoint.bpbynumber:
					if bp:
						bp.bpprint()
			return
		# parse arguments; comma has lowest precendence
		# and cannot occur in filename
		filename = None
		lineno = None
		cond = None
		comma = string.find(arg, ',')
		if comma > 0:
			# parse stuff after comma: "condition"
			cond = string.lstrip(arg[comma+1:])
			arg = string.rstrip(arg[:comma])
		# parse stuff before comma: [filename:]lineno | function
		colon = string.rfind(arg, ':')
		if colon >= 0:
			filename = string.rstrip(arg[:colon])
			f = self.lookupmodule(filename)
			if not f:
				print '*** ', `filename`,
				print 'not found from sys.path'
				return
			else:
				filename = f
			arg = string.lstrip(arg[colon+1:])
			try:
				lineno = int(arg)
			except ValueError, msg:
				print '*** Bad lineno:', arg
				return
		else:
			# no colon; can be lineno or function
			try:
				lineno = int(arg)
			except ValueError:
				try:
					func = eval(arg,
						    self.curframe.f_globals,
						    self.curframe.f_locals)
				except:
					func = arg
				try:
					if hasattr(func, 'im_func'):
						func = func.im_func
					code = func.func_code
					lineno = code.co_firstlineno
					filename = code.co_filename
				except:
					# last thing to try
					(ok, filename, ln) = self.lineinfo(arg)
					if not ok:
					    print '*** The specified object',
					    print `arg`,
					    print 'is not a function'
					    print ('or was not found '
						   'along sys.path.')
					    return
					lineno = int(ln)
		if not filename:
			filename = self.defaultFile()
		# Check for reasonable breakpoint
		line = self.checkline(filename, lineno)
		if line:
			# now set the break point
			err = self.set_break(filename, line, temporary, cond)
			if err: print '***', err

	# To be overridden in derived debuggers
	def defaultFile(self):
		# Produce a reasonable default
		filename = self.curframe.f_code.co_filename
		if filename == '<string>' and mainpyfile:
			filename = mainpyfile
		return filename

	do_b = do_break
	
	def do_tbreak(self, arg):
		self.do_break(arg, 1)

	def lineinfo(self, identifier):
		failed = (None, None, None)
		# Input is identifier, may be in single quotes
		idstring = string.split(identifier, "'")
		if len(idstring) == 1:
			# not in single quotes
			id = string.strip(idstring[0])
		elif len(idstring) == 3:
			# quoted
			id = string.strip(idstring[1])
		else:
			return failed
		if id == '': return failed
		parts = string.split(id, '.')
		# Protection for derived debuggers
		if parts[0] == 'self':
			del parts[0]
			if len(parts) == 0:
				return failed
		# Best first guess at file to look at
		fname = self.defaultFile()
		if len(parts) == 1:
			item = parts[0]
		else:
			# More than one part.
			# First is module, second is method/class
			f = self.lookupmodule(parts[0])
			if f:
				fname = f
			item = parts[1]
		grepstring = self.lineinfoCmd % (item, fname)
		answer = os.popen(grepstring, 'r').readline()
		if answer:
			f, line, junk = string.split(answer, ':', 2)
			return(item, f,line)
		else:
			return failed
		
	def checkline(self, filename, lineno):
		"""Return line number of first line at or after input
		argument such that if the input points to a 'def', the
		returned line number is the first
		non-blank/non-comment line to follow.  If the input
		points to a blank or comment line, return 0.  At end
		of file, also return 0."""

		line = linecache.getline(filename, lineno)
		if not line:
			print 'End of file'
			return 0
		line = string.strip(line)
		# Don't allow setting breakpoint at a blank line
		if ( not line or (line[0] == '#') or
		     (line[:3] == '"""') or line[:3] == "'''" ):
			print '*** Blank or comment'
			return 0
		# When a file is read in and a breakpoint is at
		# the 'def' statement, the system stops there at
		# code parse time.  We don't want that, so all breakpoints
		# set at 'def' statements are moved one line onward
		if line[:3] == 'def':
			incomment = ''
			while 1:
				lineno = lineno+1
				line = linecache.getline(filename, lineno)
				if not line:
					print 'end of file'
					return 0
				line = string.strip(line)
				if incomment:
					if len(line) < 3: continue
					if (line[-3:] == incomment):
						incomment = ''
					continue
				if not line: continue	# Blank line
				if len(line) >= 3:
					if (line[:3] == '"""'
					    or line[:3] == "'''"):
						incomment = line[:3]
						continue
				if line[0] != '#': break
		return lineno

	def do_enable(self, arg):
		args = string.split(arg)
		for i in args:
			bp = bdb.Breakpoint.bpbynumber[int(i)]
			if bp:
				bp.enable()

	def do_disable(self, arg):
		args = string.split(arg)
		for i in args:
			bp = bdb.Breakpoint.bpbynumber[int(i)]
			if bp:
				bp.disable()

	def do_condition(self, arg):
		# arg is breakpoint number and condition
		args = string.split(arg, ' ', 1)
		bpnum = int(string.strip(args[0]))
		try:
			cond = args[1]
		except:
			cond = None
		bp = bdb.Breakpoint.bpbynumber[bpnum]
		if bp:
			bp.cond = cond
			if not cond:
				print 'Breakpoint', bpnum,
				print 'is now unconditional.'

	def do_ignore(self,arg):
		# arg is bp number followed by ignore count
		args = string.split(arg)
		bpnum = int(string.strip(args[0]))
		try:
			count = int(string.strip(args[1]))
		except:
			count = 0
		bp = bdb.Breakpoint.bpbynumber[bpnum]
		if bp:
			bp.ignore = count
			if (count > 0):
				reply = 'Will ignore next '
				if (count > 1):
					reply = reply + '%d crossings' % count
				else:
					reply = reply + '1 crossing'
				print reply + ' of breakpoint %d.' % bpnum
			else:
				print 'Will stop next time breakpoint',
				print bpnum, 'is reached.'

	def do_clear(self, arg):
		if not arg:
			try:
				reply = raw_input('Clear all breaks? ')
			except EOFError:
				reply = 'no'
			reply = string.lower(string.strip(reply))
			if reply in ('y', 'yes'):
				self.clear_all_breaks()
			return
		numberlist = string.split(arg)
		for i in numberlist:
			err = self.clear_break(i)
			if err:
				print '***'+err
			else:
				print 'Deleted breakpoint %s ' % (i,)
	do_cl = do_clear # 'c' is already an abbreviation for 'continue'
	
	def do_where(self, arg):
		self.print_stack_trace()
	do_w = do_where
	
	def do_up(self, arg):
		if self.curindex == 0:
			print '*** Oldest frame'
		else:
			self.curindex = self.curindex - 1
			self.curframe = self.stack[self.curindex][0]
			self.print_stack_entry(self.stack[self.curindex])
			self.lineno = None
	do_u = do_up
	
	def do_down(self, arg):
		if self.curindex + 1 == len(self.stack):
			print '*** Newest frame'
		else:
			self.curindex = self.curindex + 1
			self.curframe = self.stack[self.curindex][0]
			self.print_stack_entry(self.stack[self.curindex])
			self.lineno = None
	do_d = do_down
	
	def do_step(self, arg):
		self.set_step()
		return 1
	do_s = do_step
	
	def do_next(self, arg):
		self.set_next(self.curframe)
		return 1
	do_n = do_next
	
	def do_return(self, arg):
		self.set_return(self.curframe)
		return 1
	do_r = do_return
	
	def do_continue(self, arg):
		self.set_continue()
		return 1
	do_c = do_cont = do_continue
	
	def do_quit(self, arg):
		self.set_quit()
		return 1
	do_q = do_quit
	
	def do_args(self, arg):
		f = self.curframe
		co = f.f_code
		dict = f.f_locals
		n = co.co_argcount
		if co.co_flags & 4: n = n+1
		if co.co_flags & 8: n = n+1
		for i in range(n):
			name = co.co_varnames[i]
			print name, '=',
			if dict.has_key(name): print dict[name]
			else: print "*** undefined ***"
	do_a = do_args
	
	def do_retval(self, arg):
		if self.curframe.f_locals.has_key('__return__'):
			print self.curframe.f_locals['__return__']
		else:
			print '*** Not yet returned!'
	do_rv = do_retval
	
	def do_p(self, arg):
		try:
			value = eval(arg, self.curframe.f_globals,
					self.curframe.f_locals)
		except:
			t, v = sys.exc_info()[:2]
			if type(t) == type(''):
				exc_type_name = t
			else: exc_type_name = t.__name__
			print '***', exc_type_name + ':', `v`
			return

		print `value`

	def do_list(self, arg):
		self.lastcmd = 'list'
		last = None
		if arg:
			try:
				x = eval(arg, {}, {})
				if type(x) == type(()):
					first, last = x
					first = int(first)
					last = int(last)
					if last < first:
						# Assume it's a count
						last = first + last
				else:
					first = max(1, int(x) - 5)
			except:
				print '*** Error in argument:', `arg`
				return
		elif self.lineno is None:
			first = max(1, self.curframe.f_lineno - 5)
		else:
			first = self.lineno + 1
		if last == None:
			last = first + 10
		filename = self.curframe.f_code.co_filename
		breaklist = self.get_file_breaks(filename)
		try:
			for lineno in range(first, last+1):
				line = linecache.getline(filename, lineno)
				if not line:
					print '[EOF]'
					break
				else:
					s = string.rjust(`lineno`, 3)
					if len(s) < 4: s = s + ' '
					if lineno in breaklist: s = s + 'B'
					else: s = s + ' '
					if lineno == self.curframe.f_lineno:
						s = s + '->'
					print s + '\t' + line,
					self.lineno = lineno
		except KeyboardInterrupt:
			pass
	do_l = do_list

	def do_whatis(self, arg):
		try:
			value = eval(arg, self.curframe.f_globals,
					self.curframe.f_locals)
		except:
			t, v = sys.exc_info()[:2]
			if type(t) == type(''):
				exc_type_name = t
			else: exc_type_name = t.__name__
			print '***', exc_type_name + ':', `v`
			return
		code = None
		# Is it a function?
		try: code = value.func_code
		except: pass
		if code:
			print 'Function', code.co_name
			return
		# Is it an instance method?
		try: code = value.im_func.func_code
		except: pass
		if code:
			print 'Method', code.co_name
			return
		# None of the above...
		print type(value)

	def do_alias(self, arg):
		args = string.split (arg)
		if len(args) == 0:
			keys = self.aliases.keys()
			keys.sort()
			for alias in keys:
				print "%s = %s" % (alias, self.aliases[alias])
			return
		if self.aliases.has_key(args[0]) and len (args) == 1:
			print "%s = %s" % (args[0], self.aliases[args[0]])
		else:
			self.aliases[args[0]] = string.join(args[1:], ' ')

	def do_unalias(self, arg):
		args = string.split (arg)
		if len(args) == 0: return
		if self.aliases.has_key(args[0]):
			del self.aliases[args[0]]

	# Print a traceback starting at the top stack frame.
	# The most recently entered frame is printed last;
	# this is different from dbx and gdb, but consistent with
	# the Python interpreter's stack trace.
	# It is also consistent with the up/down commands (which are
	# compatible with dbx and gdb: up moves towards 'main()'
	# and down moves towards the most recent stack frame).
	
	def print_stack_trace(self):
		try:
			for frame_lineno in self.stack:
				self.print_stack_entry(frame_lineno)
		except KeyboardInterrupt:
			pass
	
	def print_stack_entry(self, frame_lineno, prompt_prefix=line_prefix):
		frame, lineno = frame_lineno
		if frame is self.curframe:
			print '>',
		else:
			print ' ',
		print self.format_stack_entry(frame_lineno, prompt_prefix)


	# Help methods (derived from pdb.doc)

	def help_help(self):
		self.help_h()

	def help_h(self):
		print """h(elp)
	Without argument, print the list of available commands.
	With a command name as argument, print help about that command
	"help pdb" pipes the full documentation file to the $PAGER
	"help exec" gives help on the ! command"""

	def help_where(self):
		self.help_w()

	def help_w(self):
		print """w(here)
	Print a stack trace, with the most recent frame at the bottom.
	An arrow indicates the "current frame", which determines the
	context of most commands."""

	def help_down(self):
		self.help_d()

	def help_d(self):
		print """d(own)
	Move the current frame one level down in the stack trace
	(to an older frame)."""

	def help_up(self):
		self.help_u()

	def help_u(self):
		print """u(p)
	Move the current frame one level up in the stack trace
	(to a newer frame)."""

	def help_break(self):
		self.help_b()

	def help_b(self):
		print """b(reak) ([file:]lineno | function) [, condition]
	With a line number argument, set a break there in the current
	file.  With a function name, set a break at first executable line
	of that function.  Without argument, list all breaks.  If a second
	argument is present, it is a string specifying an expression
	which must evaluate to true before the breakpoint is honored.

	The line number may be prefixed with a filename and a colon,
	to specify a breakpoint in another file (probably one that
	hasn't been loaded yet).  The file is searched for on sys.path;
	the .py suffix may be omitted."""

	def help_clear(self):
		self.help_cl()

	def help_cl(self):
		print """cl(ear) [bpnumber [bpnumber...]]
	With a space separated list of breakpoint numbers, clear
	those breakpoints.  Without argument, clear all breaks (but
	first ask confirmation).

	Note that the argument is different from previous versions of
	the debugger (in python distributions 1.5.1 and before) where
	a linenumber was used instead of breakpoint numbers."""

	def help_tbreak(self):
		print """tbreak  same arguments as break, but breakpoint is
	removed when first hit."""

	def help_enable(self):
		print """enable bpnumber [bpnumber ...]
	Enables the breakpoints given as a space separated list of
	bp numbers."""

	def help_disable(self):
		print """disable bpnumber [bpnumber ...]
	Disables the breakpoints given as a space separated list of
	bp numbers."""

	def help_ignore(self):
		print """ignore bpnumber count
	Sets the ignore count for the given breakpoint number.  A breakpoint
	becomes active when the ignore count is zero.  When non-zero, the
	count is decremented each time the breakpoint is reached and the
	breakpoint is not disabled and any associated condition evaluates
	to true."""

	def help_condition(self):
		print """condition bpnumber str_condition
	str_condition is a string specifying an expression which
	must evaluate to true before the breakpoint is honored.
	If str_condition is absent, any existing condition is removed;
	i.e., the breakpoint is made unconditional."""

	def help_step(self):
		self.help_s()

	def help_s(self):
		print """s(tep)
	Execute the current line, stop at the first possible occasion
	(either in a function that is called or in the current function)."""

	def help_next(self):
		self.help_n()

	def help_n(self):
		print """n(ext)
	Continue execution until the next line in the current function
	is reached or it returns."""

	def help_return(self):
		self.help_r()

	def help_r(self):
		print """r(eturn)
	Continue execution until the current function returns."""

	def help_continue(self):
		self.help_c()

	def help_cont(self):
		self.help_c()

	def help_c(self):
		print """c(ont(inue))
	Continue execution, only stop when a breakpoint is encountered."""

	def help_list(self):
		self.help_l()

	def help_l(self):
		print """l(ist) [first [,last]]
	List source code for the current file.
	Without arguments, list 11 lines around the current line
	or continue the previous listing.
	With one argument, list 11 lines starting at that line.
	With two arguments, list the given range;
	if the second argument is less than the first, it is a count."""

	def help_args(self):
		self.help_a()

	def help_a(self):
		print """a(rgs)
	Print the arguments of the current function."""

	def help_p(self):
		print """p expression
	Print the value of the expression."""

	def help_exec(self):
		print """(!) statement
	Execute the (one-line) statement in the context of
	the current stack frame.
	The exclamation point can be omitted unless the first word
	of the statement resembles a debugger command.
	To assign to a global variable you must always prefix the
	command with a 'global' command, e.g.:
	(Pdb) global list_options; list_options = ['-l']
	(Pdb)"""

	def help_quit(self):
		self.help_q()

	def help_q(self):
		print """q(uit)	Quit from the debugger.
	The program being executed is aborted."""

	def help_whatis(self):
		print """whatis arg
	Prints the type of the argument."""

	def help_EOF(self):
		print """EOF
	Handles the receipt of EOF as a command."""

	def help_alias(self):
		print """alias [name [command [parameter parameter ...] ]]
	Creates an alias called 'name' the executes 'command'.  The command
	must *not* be enclosed in quotes.  Replaceable parameters are
	indicated by %1, %2, and so on, while %* is replaced by all the 
	parameters.  If no command is given, the current alias for name
	is shown. If no name is given, all aliases are listed.
	
	Aliases may be nested and can contain anything that can be
	legally typed at the pdb prompt.  Note!  You *can* override
	internal pdb commands with aliases!  Those internal commands
	are then hidden until the alias is removed.  Aliasing is recursively
	applied to the first word of the command line; all other words
	in the line are left alone.

	Some useful aliases (especially when placed in the .pdbrc file) are:

	#Print instance variables (usage "pi classInst")
	alias pi for k in %1.__dict__.keys(): print "%1.",k,"=",%1.__dict__[k]

	#Print instance variables in self
	alias ps pi self
	"""

	def help_unalias(self):
		print """unalias name
	Deletes the specified alias."""

	def help_pdb(self):
		help()

	# Helper function for break/clear parsing -- may be overridden

	def lookupmodule(self, filename):
		root, ext = os.path.splitext(filename)
		if ext == '':
			filename = filename + '.py'
		if os.path.isabs(filename):
			return filename
		for dirname in sys.path:
			while os.path.islink(dirname):
				dirname = os.readlink(dirname)
			fullname = os.path.join(dirname, filename)
			if os.path.exists(fullname):
				return fullname
		return None

# Simplified interface

def run(statement, globals=None, locals=None):
	Pdb().run(statement, globals, locals)

def runeval(expression, globals=None, locals=None):
	return Pdb().runeval(expression, globals, locals)

def runctx(statement, globals, locals):
	# B/W compatibility
	run(statement, globals, locals)

def runcall(*args):
	return apply(Pdb().runcall, args)

def set_trace():
	Pdb().set_trace()

# Post-Mortem interface

def post_mortem(t):
	p = Pdb()
	p.reset()
	while t.tb_next <> None: t = t.tb_next
	p.interaction(t.tb_frame, t)

def pm():
	post_mortem(sys.last_traceback)


# Main program for testing

TESTCMD = 'import x; x.main()'

def test():
	run(TESTCMD)

# print help
def help():
	for dirname in sys.path:
		fullname = os.path.join(dirname, 'pdb.doc')
		if os.path.exists(fullname):
			sts = os.system('${PAGER-more} '+fullname)
			if sts: print '*** Pager exit status:', sts
			break
	else:
		print 'Sorry, can\'t find the help file "pdb.doc"',
		print 'along the Python search path'

mainmodule = ''
mainpyfile = ''

# When invoked as main program, invoke the debugger on a script
if __name__=='__main__':
	global mainmodule, mainpyfile
	if not sys.argv[1:]:
		print "usage: pdb.py scriptfile [arg] ..."
		sys.exit(2)

	mainpyfile = filename = sys.argv[1]	# Get script filename
	if not os.path.exists(filename):
		print 'Error:', `filename`, 'does not exist'
		sys.exit(1)
	mainmodule = os.path.basename(filename)
	del sys.argv[0]		# Hide "pdb.py" from argument list

	# Insert script directory in front of module search path
	sys.path.insert(0, os.path.dirname(filename))

	run('execfile(' + `filename` + ')', {'__name__': '__main__'})
