# pdb.py -- finally, a Python debugger!
# See file pdb.doc for instructions.

# To do:
# - It should be possible to intercept KeyboardInterrupt
# - Handle return events differently -- always printing the r.v. can be bad!
# - Merge with tb, to get a single debugger for active and post-mortem usage
# - Solve bugs in termination (e.g., 'continue' after the program
#   is done proceeds to debug the debugger; 'quit' sometimes complains
#   about the PdbQuit exception...)


import string
import sys
import linecache
from cmd import Cmd


# A specialization of Cmd for use by the debugger

PdbQuit = 'pdb.PdbQuit' # Exception to give up

class Pdb(Cmd):
	
	def init(self):
		self = Cmd.init(self)
		self.prompt = '(Pdb) '
		self.reset()
		return self
	
	def reset(self):
		self.quitting = 0
		self.breaks = {}
		self.botframe = None
		self.stopframe = None
		self.lastretval = None
		self.forget()
	
	def forget(self):
		self.setup(None, None)
	
	def setup(self, f, t):
		self.lineno = None
		self.stack = []
		self.curindex = 0
		self.curframe = None
		if f is None and t is None:
			return
		if t and t.tb_frame is f:
			t = t.tb_next
		while f is not None:
			self.stack.append((f, f.f_lineno))
			if f is self.botframe:
				break
			f = f.f_back
		else:
			print '[Weird: bottom frame not in stack trace.]'
		self.stack.reverse()
		self.curindex = max(0, len(self.stack) - 1)
		while t is not None:
			self.stack.append((t.tb_frame, t.tb_lineno))
			t = t.tb_next
		self.curframe = self.stack[self.curindex][0]
	
	def run(self, cmd):
		import __main__
		dict = __main__.__dict__
		self.runctx(cmd, dict, dict)
	
	def runctx(self, cmd, globals, locals):
		t = None
		self.reset()
		sys.trace = self.dispatch
		try:
			exec(cmd + '\n', globals, locals)
		except PdbQuit:
			return
		except:
			print '***', sys.exc_type + ':', `sys.exc_value`
			t = sys.exc_traceback
		finally:
			self.trace = None
			del self.trace
			self.forget()
		print '!!! Post-mortem debugging'
		self.pmd(t)
	
	def pmd(self, traceback):
		t = traceback
		if self.botframe is not None:
			while t is not None:
				if t.tb_frame is not self.botframe:
					break
				t = t.tb_next
			else:
				t = sys.exc_traceback
		try:
			self.ask_user(self.botframe, t)
		except PdbQuit:
			pass
		finally:
			self.forget()
	
	def dispatch(self, frame, event, arg):
		if self.quitting:
			return None
		if event == 'line':
			return self.dispatch_line(frame)
		if event == 'call':
			return self.dispatch_call(frame, arg)
		if event == 'return':
			return self.dispatch_return(frame, arg)
		if event == 'exception':
			return self.dispatch_exception(frame, arg)
		print '*** dispatch: unknown event type', `event`
		return self.dispatch
	
	def dispatch_line(self, frame):
		if self.stop_here(frame) or self.break_here(frame):
			self.ask_user(frame, None)
		return self.dispatch
	
	def dispatch_call(self, frame, arg):
		if self.botframe is None:
			# First call dispatch since reset()
			self.botframe = frame
			return None
		if not (self.stop_here(frame) or self.break_anywhere(frame)):
			return None
		if arg is None:
			print '[Entering non-function block.]'
		else:
			frame.f_locals['__args__'] = arg
		return self.dispatch
	
	def dispatch_return(self, frame, arg):
		self.lastretval = arg
		return None
	
	def dispatch_exception(self, frame, arg):
		if self.stop_here(frame):
			print '!!!', arg[0] + ':', `arg[1]`
			self.ask_user(frame, arg[2])
		return self.dispatch
	
	def stop_here(self, frame):
		if self.stopframe is None:
			return 1
		if frame is self.stopframe:
			return 1
		while frame is not None and frame is not self.stopframe:
			if frame is self.botframe:
				return 1
			frame = frame.f_back
		return 0
	
	def break_here(self, frame):
		if not self.breaks.has_key(frame.f_code.co_filename):
			return 0
		if not frame.f_lineno in \
			self.breaks[frame.f_code.co_filename]:
			return 0
		return 1
	
	def break_anywhere(self, frame):
		return self.breaks.has_key(frame.f_code.co_filename)
	
	def ask_user(self, frame, traceback):
		self.setup(frame, traceback)
		self.printframelineno(self.stack[self.curindex])
		self.cmdloop()
		self.forget()
	
	def default(self, line):
		if not line:
			return self.do_next('')
		else:
			if line[0] == '!': line = line[1:]
			try:
				exec(line + '\n', \
					self.curframe.f_globals, \
					self.curframe.f_locals)
			except:
				print '***', sys.exc_type				 + ':',
				print `sys.exc_value`
	
	do_h = Cmd.do_help
	
	def do_break(self, arg):
		if not arg:
			print self.breaks # XXX
			return
		try:
			lineno = int(eval(arg))
		except:
			print '*** Error in argument:', `arg`
			return
		filename = self.curframe.f_code.co_filename
		line = linecache.getline(filename, lineno)
		if not line:
			print '*** That line does not exist!'
			return
		if not self.breaks.has_key(filename):
			self.breaks[filename] = []
		list = self.breaks[filename]
		if lineno in list:
			print '*** There is already a break there!'
			return
		list.append(lineno)
	do_b = do_break
	
	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.breaks = {}
			return
		try:
			lineno = int(eval(arg))
		except:
			print '*** Error in argument:', `arg`
			return
		filename = self.curframe.f_code.co_filename
		try:
			self.breaks[filename].remove(lineno)
		except (ValueError, KeyError):
			print '*** There is no break there!'
			return
		if not self.breaks[filename]:
			del self.breaks[filename]
	do_cl = do_clear # 'c' is already an abbreviation for 'continue'
	
	def do_where(self, arg):
		self.printstacktrace()
	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.printframelineno(self.stack[self.curindex])
	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.printframelineno(self.stack[self.curindex])
	do_d = do_down
	
	def do_step(self, arg):
		self.stopframe = None
		return 1
	do_s = do_step
	
	def do_next(self, arg):
		self.stopframe = self.curframe
		return 1
	do_n = do_next
	
	def do_return(self, arg):
		self.stopframe = self.curframe.f_back
		return 1
	do_r = do_return
	
	def do_retval(self, arg):
		print self.lastretval
	do_rv = do_retval
	
	def do_continue(self, arg):
		self.stopframe = self.botframe
		return 1
	do_c = do_cont = do_continue
	
	def do_quit(self, arg):
		self.quitting = 1
		sys.trace = None; del sys.trace
		raise PdbQuit
	do_q = do_quit
	
	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 = int(x)
			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 is None:
			last = first + 10
		filename = self.curframe.f_code.co_filename
		if self.breaks.has_key(filename):
			breaklist = self.breaks[filename]
		else:
			breaklist = []
		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_args(self, arg):
		try:
			value = eval('__args__', self.curframe.f_globals, \
					self.curframe.f_locals)
		except:
			print '***', sys.exc_type + ':', `sys.exc_value`
			return
		print `value`
	do_a = do_args
	
	def do_p(self, arg):
		try:
			value = eval(arg, self.curframe.f_globals, \
					self.curframe.f_locals)
		except:
			print '***', sys.exc_type + ':', `sys.exc_value`
			return
		print `value`

	# Print a traceback starting at the top stack frame.
	# Note that 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 printstacktrace(self):
		for x in self.stack:
			self.printframelineno(x)
	
	def printframelineno(self, (frame, lineno)):
		if frame is self.curframe: print '->',
		code = frame.f_code
		filename = code.co_filename
		print filename + '(' + `lineno` + ')',
		line = linecache.getline(filename, lineno)
		print string.strip(line),
		print


def run(statement):
	Pdb().init().run(statement)

def runctx(statement, globals, locals):
	Pdb().init().runctx(statement, globals, locals)


# --------------------- testing ---------------------

# The Ackermann function -- a highly recursive beast
cheat = 2
cache = {}
def ack(x, y):
	key = `(long(x), long(y))`
	if cache.has_key(key):
		res = cache[key]
	else:
		if x == 0:
			res = 1L
		elif y == 0:
			if x == 1:
				res = 2L
			else:
				res = 2L + x
		elif y == 1 and cheat >= 1:
			res = 2L * x
		elif y == 2 and cheat >= 2:
			res = pow(2L, x)
		else:
			res = ack(ack(x-1, y), y-1)
		cache[key] = res
	return res

def foo(n):
	print 'foo', n
	x = bar(n*2)
	print 'bar returned', x
	y = ack(4, 3)
	return y

def bar(a):
	print 'bar', a
	return a*10

def melt(n):
	print 1.0/n
	melt(n-1)

def test():
	linecache.checkcache()
	runctx('from pdb import foo; foo(12)', {}, {})
	runctx('from pdb import melt; melt(5)', {}, {})


# --------------------- main ---------------------

import os

def main():
	if sys.argv[1:]:
		file = sys.argv[1]
		head, tail = os.path.split(file)
		if tail[-3:] != '.py':
			print 'Sorry, file arg must be a python module'
			print '(i.e., must end in \'.py\')'
			# XXX Or we could copy it to a temp file
			sys.exit(2)
		del sys.argv[0]
		sys.path.insert(0, head)
		run('import ' + tail[:-3])
	else:
		run(raw_input('Python statement to debug: '))
