summaryrefslogtreecommitdiff
path: root/examples/ide/gtkdb.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/ide/gtkdb.py')
-rwxr-xr-xexamples/ide/gtkdb.py350
1 files changed, 350 insertions, 0 deletions
diff --git a/examples/ide/gtkdb.py b/examples/ide/gtkdb.py
new file mode 100755
index 00000000..6874d34b
--- /dev/null
+++ b/examples/ide/gtkdb.py
@@ -0,0 +1,350 @@
+#!/usr/bin/env python
+
+import sys
+import bdb
+import repr
+import string
+import linecache # for linecache.getlines(filename)
+from gtk import *
+import GtkExtra
+
+class GtkDb(GtkWindow, bdb.Bdb):
+ def __init__(self):
+ GtkWindow.__init__(self)
+ bdb.Bdb.__init__(self)
+ self.realize()
+
+ self.set_title("GtkDb")
+ self.connect("destroy", self.do_quit)
+ self.connect("delete_event", self.do_quit)
+
+ self.box = GtkVBox()
+ self.add(self.box)
+ self.box.show()
+
+ toolbar = GtkToolbar(ORIENTATION_HORIZONTAL, TOOLBAR_BOTH)
+ toolbar.set_space_size(10)
+ self.box.pack_start(toolbar, expand=FALSE)
+ toolbar.show()
+
+ toolbar.append_item("next", "Next statement", None,
+ GtkPixmap(self, "next.xpm"), self.do_next)
+ toolbar.append_item("step", "Step into function", None,
+ GtkPixmap(self, "step.xpm"), self.do_step)
+ toolbar.append_space()
+ toolbar.append_item("return",
+ "Continue execution to end of function",
+ None, GtkPixmap(self, "return.xpm"),
+ self.do_return)
+ toolbar.append_space()
+ toolbar.append_item("continue",
+ "Continue execution to next break point",
+ None, GtkPixmap(self, "continue.xpm"),
+ self.do_continue)
+ toolbar.append_item("break",
+ "toggle break point at selected line",None,
+ GtkPixmap(self,"break.xpm"),self.do_break)
+ toolbar.append_space()
+ toolbar.append_item("edit",
+ "edit the value of the selected variable",
+ None, GtkPixmap(self, "edit.xpm"),
+ self.do_edit)
+ toolbar.append_item("run",
+ "Execute some code in the current stack context",
+ None, GtkPixmap(self, "run.xpm"),
+ self.do_run)
+ toolbar.append_space()
+ toolbar.append_item("quit", "Quit the debugger", None,
+ GtkPixmap(self, "quit.xpm"), self.do_quit)
+
+ sep = GtkHSeparator()
+ self.box.pack_start(sep, expand=FALSE)
+ sep.show()
+
+ vpane = GtkVPaned()
+ self.box.pack_start(vpane)
+ vpane.show()
+
+ hpane = GtkHPaned()
+ vpane.add1(hpane)
+ hpane.show()
+
+ self.stackdisp = GtkCList(1, ['Stack Frame'])
+ self.stackdisp.connect("select_row", self.update_curstack)
+ self.stackdisp.set_usize(280, 125)
+ self.stackdisp.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
+ self.stackdisp.set_selection_mode(SELECTION_BROWSE)
+ self.stackdisp.border_width(2)
+ hpane.add1(self.stackdisp)
+ self.stackdisp.show()
+
+ self.vardisp = GtkCList(3, ['local var', 'type', 'value'])
+ self.vardisp.connect("select_row", self.update_selectedvar)
+ self.vardisp.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
+ self.vardisp.set_selection_mode(SELECTION_BROWSE)
+ self.vardisp.set_column_width(0, 75)
+ self.vardisp.set_column_width(1, 30)
+ self.vardisp.border_width(2)
+ hpane.add2(self.vardisp)
+ self.vardisp.show()
+ self.vardisp.selected = 0
+ self.vardisp.varnames = []
+
+ self.filedisp = GtkCList(3, ['break', 'lineno', 'line'])
+ self.minibreak = GtkPixmap(self, "minibreak.xpm")
+ # This is giving a warning -- probably a bug in GTK
+ self.filedisp.set_column_widget(0, self.minibreak)
+ self.filedisp.column_titles_show()
+ self.filedisp.set_column_width(0, 14)
+ self.filedisp.set_column_width(1, 35)
+ self.filedisp.connect("select_row", self.update_selection)
+ self.filedisp.set_column_justification(1, JUSTIFY_RIGHT)
+ self.filedisp.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
+ self.filedisp.set_selection_mode(SELECTION_BROWSE)
+ self.filedisp.border_width(2)
+ self.filedisp.set_usize(600, 200)
+ vpane.add2(self.filedisp)
+ self.filedisp.show()
+
+ separator = GtkHSeparator()
+ self.box.pack_start(separator, expand=FALSE)
+ separator.show()
+
+ align = GtkAlignment(0.0, 0.5, 0.0, 0.0)
+ self.box.pack_start(align, expand=FALSE)
+ align.show()
+ self.status = GtkLabel()
+ self.status.set_padding(4, 1)
+ align.add(self.status)
+ self.status.show()
+
+ self.filename = None
+ self.selected = 0
+ self.blockupdate = 0
+
+ def set_status(self, str):
+ self.status.set(str)
+
+ def update_selection(self, clist, r, c, event):
+ if self.blockupdate: return
+ self.selected = r + 1
+ if c == 0: # break point column
+ self.do_break()
+
+ def update_curstack(self, clist, r, c, event):
+ if self.blockupdate: return
+ self.curindex = r
+ self.curframe = self.stack[self.curindex][0]
+ self.lineno = None
+ self.update_code_listing()
+ self.update_var_listing()
+
+ def update_selectedvar(self, clist, r, c, event):
+ self.vardisp.selected = r
+
+ def set_quit(self):
+ self.hide()
+ self.destroy()
+ bdb.Bdb.set_quit(self)
+
+ 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]
+
+ # interaction functions -- overriden from bdb
+ def user_line(self, frame):
+ # called when we stop or break at this line
+ self.interaction(frame, None)
+ def user_return(self, frame, return_value):
+ # called when a return trap is set here
+ frame.f_locals['__return__'] = return_value
+ if frame.f_code.co_name:
+ func = frame.f_code.co_name
+ else:
+ func = "<lambda>"
+ self.set_status(func + " rerturned " + repr.repr(return_value))
+ self.interaction(frame, None)
+ def user_exception(self, frame, (exc_type, exc_value, exc_traceback)):
+ 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__
+ self.set_status(exc_type_name + ':' + repr.repr(exc_value))
+ self.interaction(frame, exc_traceback)
+
+ def interaction(self, frame, traceback):
+ self.setup(frame, traceback)
+ self.update_stack_listing(self.curindex)
+ mainloop()
+ self.forget()
+
+ def update_stack_listing(self, curindex):
+ self.stackdisp.freeze()
+ self.blockupdate = 1
+ self.stackdisp.clear()
+ for i in range(len(self.stack)):
+ frame_lineno = self.stack[i]
+ row = self.format_stack_entry(frame_lineno, "##!##")
+ row = string.split(row, "##!##")[0]
+ self.stackdisp.append([row])
+ self.blockupdate = 0
+ self.stackdisp.moveto(curindex, 0, 1.0, 0.0)
+ self.stackdisp.select_row(curindex, 0)
+ self.stackdisp.thaw()
+
+ def update_var_listing(self):
+ self.vardisp.freeze()
+ self.vardisp.clear()
+ locals = self.curframe.f_locals
+ self.vardisp.varnames = locals.keys()
+ self.vardisp.varnames.sort()
+ for var in self.vardisp.varnames:
+ row = [var, type(locals[var]).__name__, repr.repr(
+ locals[var])]
+ self.vardisp.append(row)
+ self.vardisp.thaw()
+
+ def update_code_listing(self):
+ frame = self.curframe
+ newfile = frame.f_code.co_filename
+ if newfile != self.filename:
+ lines = linecache.getlines(newfile)
+ self.filename = newfile
+ self.filedisp.freeze()
+ self.blockupdate = 1
+ self.filedisp.clear()
+ breaks = self.get_file_breaks(newfile)
+ for line in range(len(lines)):
+ self.filedisp.append(['', repr.repr(line+1),
+ lines[line]])
+ if line+1 in breaks:
+ self.filedisp.set_pixmap(line, 0,
+ self.minibreak)
+ self.blockupdate = 0
+ self.filedisp.thaw()
+ self.selected = frame.f_lineno
+ lineno = self.selected
+ self.filedisp.moveto(lineno - 1, 2)
+ self.filedisp.select_row(lineno - 1, 2)
+
+ def do_next(self, _b=None):
+ self.set_next(self.curframe)
+ mainquit()
+ def do_step(self, _b=None):
+ self.set_step()
+ mainquit()
+ def do_return(self, _b=None):
+ self.set_return(self.curframe)
+ mainquit()
+ def do_continue(self, _b=None):
+ self.set_continue()
+ mainquit()
+ def do_quit(self, _b=None, _e=None):
+ self.set_quit()
+ mainquit()
+ def do_break(self, _b=None):
+ breaks = self.get_file_breaks(self.filename)
+ if self.selected in breaks:
+ err = self.clear_break(self.filename, self.selected)
+ if err:
+ self.set_status(err)
+ return
+ self.filedisp.set_text(self.selected-1, 0, ' ')
+ else:
+ err = self.set_break(self.filename, self.selected)
+ if err:
+ self.set_status(err)
+ return
+ self.filedisp.set_pixmap(self.selected-1, 0,
+ self.minibreak)
+ def do_run(self, _b=None):
+ line = GtkExtra.input_box("Execute Code",
+ "Enter code to execute:")
+ if line == None: return
+ locals = self.curframe.f_locals
+ globals = self.curframe.f_globals
+ globals['__privileged__'] = 1
+ try:
+ code = compile(line + '\n', '<stdin>', 'single')
+ exec code in globals, locals
+ except:
+ if type(sys.exc_type) == type(''):
+ exc_type_name = sys.exc_type
+ else: exc_type_name = sys.exc_type.__name__
+ self.set_status('*** ' + exc_type_name + ': ' +
+ str(sys.exc_value))
+ return
+ self.update_var_listing()
+
+ def do_edit(self, _b=None):
+ locals = self.curframe.f_locals
+ varname = self.vardisp.varnames[self.vardisp.selected]
+ val = repr.repr(locals[varname])
+ value = GtkExtra.input_box("Edit Variable",
+ "Enter new value for" + varname + ":", val)
+ if value == None: return
+ globals = self.curframe.f_globals
+ globals['__privileged__'] = 1
+ try:
+ val = eval(value, globals, locals)
+ self.curframe.f_locals[varname] = val
+ except:
+ if type(sys.exc_type) == type(''):
+ exc_type_name = sys.exc_type
+ else: exc_type_name = sys.exc_type.__name__
+ self.set_status('*** ' + exc_type_name + ': ' +
+ str(sys.exc_value))
+ return
+ row = self.vardisp.selected
+ self.vardisp.set_text(row, 1, type(val).__name__)
+ self.vardisp.set_text(row, 2, repr.repr(val))
+
+# this makes up the interface that is compatible with pdb.
+def run(statement, globals=None, locals=None):
+ win = GtkDb()
+ win.show()
+ win.run(statement, globals, locals)
+
+def runeval(expression, globals=None, locals=None):
+ win = GtkDb()
+ win.show()
+ return win.runeval(expression, globals, locals)
+
+def runcall(*args):
+ win = GtkDb()
+ win.show()
+ return apply(win.runcall, args)
+
+def set_trace():
+ win = GtkDb()
+ win.show()
+ win.set_trace()
+
+def post_mortem(traceback):
+ win = GtkDb()
+ win.show()
+ win.reset()
+ win.interaction(None, traceback)
+
+def pm():
+ post_mortem(sys.last_traceback)
+
+if __name__ == '__main__':
+ import os
+ if not sys.argv[1:]:
+ print "usage: gtkdb.py scriptfile [args ...]"
+ sys.exit(2)
+ filename = sys.argv[1]
+ del sys.argv[0] # delete gtkdb.py
+ sys.path.insert(0, os.path.dirname(filename))
+
+ run('execfile("' + filename + '")', {'__name__': '__main__'})