# THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
# APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
# HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
# OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
# IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
# ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

# IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
# WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
# THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
# GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
# USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
# DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
# PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
# EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGES.

# Copyright (c) 2018 Dr. Oliver Barth <info@drb-electronic.de>
# Extends the python basic debugger

import bdb
import time

#
class BdbExt(bdb.Bdb):
	#
	def __init__(self):
		bdb.Bdb.__init__(self)
		self.lineno = 0
		self.break_active = 0
		self.step_active = 0
		self.calls = 0

	#
	def user_call(self, frame, args):
		self.calls = self.calls + 1

	#
	def user_line(self, frame):
		if self.calls > 0:
			return
			
		self.actFrame = frame
		self.lineno = frame.f_lineno
		
		# breakpoint
		filename = self.canonic(frame.f_code.co_filename)
		if self.get_breaks(filename, frame.f_lineno):
			self.break_active = 1

		# break
		while self.break_active == 1:
			time.sleep(0.1)

		if self.break_active == 2:
			self.break_active = 1

	#
	def user_return(self, frame, value):
		self.calls = self.calls - 1

	#
	def user_exception(self, frame, exception):
		pass

	#
	def getLineno(self):
		return self.lineno
		
	#
	def dbg_break(self):
		self.break_active = 1

	#
	def dbg_step(self):
		self.break_active = 2

	#
	def dbg_cont(self):
		self.break_active = 0
		
	#
	def dbg_print(self, arg):
		ret = ''
		try:
			ret = eval(arg, self.actFrame.f_globals, self.actFrame.f_locals)
		except (SyntaxError, NameError, TypeError, ZeroDivisionError):
			ret = 'variable not found'
		return ret

