[nemiver/jump-to: 1/5] 560235 Initial support of "jump to"
- From: Dodji Seketeli <dodji src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nemiver/jump-to: 1/5] 560235 Initial support of "jump to"
- Date: Mon, 25 Apr 2011 13:17:27 +0000 (UTC)
commit 372c7d3bf49a999e8ad1941338d7673efddbb6ac
Author: Dodji Seketeli <dodji seketeli org>
Date: Thu Apr 21 22:22:36 2011 +0200
560235 Initial support of "jump to"
* src/dbgengine/nmv-i-debugger.h (IDebugger::jump_to_position):
New entry point.
(IDebugger::set_breakpoint, IDebugger::enable_breakpoint): New
overloads taking callback slots.
* src/dbgengine/nmv-gdb-engine.h (GDBEngine::jump_to_position)
(GDBEngine::enable_breakpoint): Declare these functions.
* src/dbgengine/nmv-gdb-engine.cc
(OnBreakpointHandler::do_handle): Support callback slots for
'-break-enable' and 'jump-to-position'.
(GDBEngine::jump_to_position, location_to_string): Define new
functions.
(GDBEngine::enable_breakpoint): Likewise. Rewrite the other
overload in terms of this one.
* src/uicommon/nmv-source-editor.cc
(SourceEditor::current_location): New overload that returns a
pointer to const Loc.
* src/uicommon/nmv-source-editor.h: Likewise.
* src/persp/nmv-set-jump-to-dialog.h: New file.
* rc/persp/nmv-set-jump-to-dialog.cc: Likewise.
* src/persp/dbgperspective/ui/setjumptodialog.ui: Likewise.
* src/persp/dbgperspective/ui/Makefile.am: Add setjumptodialog.ui
to build system.
* src/persp/dbgperspective/Makefile.am: Add
nmv-set-jump-to-dialog.h and nmv-set-jump-to-dialog.cc to the
build system.
* src/persp/dbgperspective/nmv-dbg-perspective.cc
(DBGPerspective::on_jump_to_current_location_action)
(DBGPerspective::on_jump_and_break_to_current_location_action)
(DBGPerspective::on_break_before_jump)
(DBGPerspective::do_jump_to_current_location)
(DBGPerspective::do_jump_and_break_to_current_location)
(DBGPerspective::jump_to_location)
(DBGPerspective::on_jump_to_location_action)
(DBGPerspective::do_jump_and_break_to_location)
(DBGPerspective::jump_to_location_from_dialog)
(DBGPerspective::is_breakpoint_set_at_location): New functions.
(DBGPerspective::on_debugger_breakpoints_set_signal): Minor style
cleanup.
(DBGPerspective::init_actions): Add
JumpToCurrentLocationMenuItemAction and
JumpAndBreakToCurrentLocationMenuItemAction actions. Add a menu
item to display a dialog to jump to a given location.
(DBGPerspective::get_contextual_menu): Add two new menu items for
actions JumpToCurrentLocationMenuItemAction and
(DBGPerspective::is_breakpoint_set_at_address): Add a boolean
output parameter to get the enable-ness of the breakpoint.
(DBGPerspective::get_breakpoint): New overload that takes a
location in argument.
(DBGPerspective::is_breakpoint_set_at_line): Add comment.
(DBGPerspective::toggle_breakpoint): Adjust for the new signature
of is_breakpoint_set_at_address.
JumpAndBreakToCurrentLocationMenuItemAction.
* src/persp/dbgperspective/menus/menus.xml: Add add menu item to
jump to a specified location.
* po/POTFILES.in: Add
src/persp/dbgperspective/ui/setjumptodialog.ui to the list of
files containing translatable strings.
po/POTFILES.in | 1 +
src/dbgengine/nmv-gdb-engine.cc | 92 ++++-
src/dbgengine/nmv-gdb-engine.h | 7 +
src/dbgengine/nmv-i-debugger.h | 13 +
src/persp/dbgperspective/Makefile.am | 4 +-
src/persp/dbgperspective/menus/menus.xml | 5 +-
src/persp/dbgperspective/nmv-dbg-perspective.cc | 422 +++++++++++++++++++-
src/persp/dbgperspective/nmv-set-jump-to-dialog.cc | 428 ++++++++++++++++++++
src/persp/dbgperspective/nmv-set-jump-to-dialog.h | 57 +++
src/persp/dbgperspective/ui/Makefile.am | 3 +-
src/persp/dbgperspective/ui/setjumptodialog.ui | 281 +++++++++++++
src/uicommon/nmv-source-editor.cc | 31 ++
src/uicommon/nmv-source-editor.h | 3 +
13 files changed, 1324 insertions(+), 23 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 3b727c5..f48c425 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -16,6 +16,7 @@ src/uicommon/nmv-locate-file-dialog.cc
[type: gettext/glade]src/persp/dbgperspective/ui/chooseoverloadsdialog.ui
[type: gettext/glade]src/persp/dbgperspective/ui/remotetargetdialog.ui
[type: gettext/glade]src/persp/dbgperspective/ui/setbreakpointdialog.ui
+[type: gettext/glade]src/persp/dbgperspective/ui/setjumptodialog.ui
src/persp/dbgperspective/nmv-choose-overloads-dialog.cc
[type: gettext/glade]src/persp/dbgperspective/ui/globalvarsinspector.ui
[type: gettext/glade]src/persp/dbgperspective/ui/watchpointdialog.ui
diff --git a/src/dbgengine/nmv-gdb-engine.cc b/src/dbgengine/nmv-gdb-engine.cc
index 8cdc886..01f525e 100644
--- a/src/dbgengine/nmv-gdb-engine.cc
+++ b/src/dbgengine/nmv-gdb-engine.cc
@@ -141,20 +141,20 @@ location_to_string (const Loc &a_loc,
THROW ("Should not be reached");
case Loc::SOURCE_LOC_KIND: {
- const SourceLoc *loc = static_cast<const SourceLoc*> (&a_loc);
- location_to_string (*loc, a_str);
+ const SourceLoc &loc = static_cast<const SourceLoc&> (a_loc);
+ location_to_string (loc, a_str);
}
break;
case Loc::FUNCTION_LOC_KIND: {
- const FunctionLoc *loc = static_cast<const FunctionLoc*> (&a_loc);
- location_to_string (*loc, a_str);
+ const FunctionLoc &loc = static_cast<const FunctionLoc&> (a_loc);
+ location_to_string (loc, a_str);
}
break;
case Loc::ADDRESS_LOC_KIND: {
- const AddressLoc *loc = static_cast<const AddressLoc*> (&a_loc);
- location_to_string (*loc, a_str);
+ const AddressLoc &loc = static_cast<const AddressLoc&> (a_loc);
+ location_to_string (loc, a_str);
}
break;
}
@@ -1726,6 +1726,13 @@ struct OnCommandDoneHandler : OutputHandler {
}
}
+ if (a_in.command ().name () == "-break-enable"
+ && a_in.command ().has_slot ()) {
+ IDebugger::BreakpointsSlot slot =
+ a_in.command ().get_slot<IDebugger::BreakpointsSlot> ();
+ slot (m_engine->get_cached_breakpoints ());
+ }
+
// So, if we are still attached to the target and we receive
// a "DONE" response from GDB, it means we are READY.
// But if we are not attached -- which can mean that the
@@ -1764,7 +1771,13 @@ struct OnRunningHandler : OutputHandler {
void do_handle (CommandAndOutput &a_in)
{
LOG_FUNCTION_SCOPE_NORMAL_DD;
- if (a_in.has_command ()) {}
+
+ Command &c = a_in.command ();
+ if (c.name () == "jump-to-position"
+ && c.has_slot ()) {
+ IDebugger::DefaultSlot s = c.get_slot<IDebugger::DefaultSlot> ();
+ s ();
+ }
m_engine->running_signal ().emit ();
}
};//struct OnRunningHandler
@@ -3898,6 +3911,30 @@ GDBEngine::continue_to_position (const UString &a_path,
a_cookie));
}
+/// Jump to a location in the inferior.
+///
+/// Execution is then resumed from the new location.
+///
+/// \param a_loc the location to jump to
+///
+/// \param a_slot a callback function that is invoked once the jump is
+/// done.
+void
+GDBEngine::jump_to_position (const Loc &a_loc,
+ const DefaultSlot &a_slot)
+{
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+ UString location;
+
+ location_to_string (a_loc, location);
+
+ Command command ("jump-to-position",
+ "-exec-jump " + location);
+ command.set_slot (a_slot);
+ queue_command (command);
+}
+
/// Set a breakpoint at a location in the inferior.
///
/// \param a_loc the location of the breakpoint.
@@ -4012,18 +4049,51 @@ GDBEngine::set_breakpoint (const Address &a_address,
queue_command (Command (cmd_name, break_cmd, a_cookie));
}
+/// Enable a given breakpoint
+///
+/// \param a_break_num the ID of the breakpoint to enable.
+///
+/// \param a_slot a callback slot invoked upon completion of the
+/// command by GDB.
+///
+/// \param a_cookie a string passed as an argument to
+/// IDebugger::breakpoints_set_signal upon completion of the command
+/// by GDB. Note that both a_slot and
+/// IDebugger::breakpoints_set_signal are invoked upon completion of
+/// the command by GDB for now. Eventually only a_slot will be kept;
+/// IDebugger::breakpoints_set_signal will be dropped. We in a
+/// transitional period at the moment.
void
GDBEngine::enable_breakpoint (gint a_break_num,
+ const BreakpointsSlot &a_slot,
const UString &a_cookie)
{
LOG_FUNCTION_SCOPE_NORMAL_DD;
- queue_command (Command ("enable-breakpoint",
- "-break-enable "
- + UString::from_int (a_break_num),
- a_cookie));
+
+ Command command ("enable-breakpoint",
+ "-break-enable "
+ + UString::from_int (a_break_num));
+ command.set_slot (a_slot);
+ queue_command (command);
list_breakpoints (a_cookie);
}
+/// Enable a given breakpoint
+///
+/// \param a_break_num the ID of the breakpoint to enable.
+///
+/// \param a_cookie a string passed as an argument to
+/// IDebugger::breakpoints_set_signal upon completion of the command
+/// by GDB. Eventually this function should be dropped and we should
+/// keep the one above.
+void
+GDBEngine::enable_breakpoint (gint a_break_num,
+ const UString &a_cookie)
+{
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+ enable_breakpoint (a_break_num, &null_breakpoints_slot, a_cookie);
+}
+
void
GDBEngine::disable_breakpoint (gint a_break_num,
const UString &a_cookie)
diff --git a/src/dbgengine/nmv-gdb-engine.h b/src/dbgengine/nmv-gdb-engine.h
index f907081..980b61a 100644
--- a/src/dbgengine/nmv-gdb-engine.h
+++ b/src/dbgengine/nmv-gdb-engine.h
@@ -333,6 +333,9 @@ public:
gint a_line_num,
const UString &a_cookie) ;
+ void jump_to_position (const Loc &a_loc,
+ const DefaultSlot &a_slot);
+
void set_breakpoint (const Loc &a_loc,
const UString &a_condition,
gint a_ignore_count,
@@ -356,6 +359,10 @@ public:
const UString &a_cookie);
void enable_breakpoint (gint a_break_num,
+ const BreakpointsSlot &a_slot,
+ const UString &a_cookie = "");
+
+ void enable_breakpoint (gint a_break_num,
const UString &a_cookie="");
void disable_breakpoint (gint a_break_num,
diff --git a/src/dbgengine/nmv-i-debugger.h b/src/dbgengine/nmv-i-debugger.h
index a2dbac9..b375798 100644
--- a/src/dbgengine/nmv-i-debugger.h
+++ b/src/dbgengine/nmv-i-debugger.h
@@ -822,9 +822,15 @@ public:
}
typedef sigc::slot<void> DefaultSlot;
+
typedef sigc::slot<void,
const std::pair<int, const IDebugger::Breakpoint&>&>
BreakpointSlot;
+
+ typedef sigc::slot<void,
+ const std::map<int, IDebugger::Breakpoint>&>
+ BreakpointsSlot;
+
typedef sigc::slot<void, Loc&> LocSlot;
virtual ~IDebugger () {}
@@ -1128,6 +1134,9 @@ public:
gint a_line_num,
const UString &a_cookie="") = 0;
+ virtual void jump_to_position (const Loc &a_loc,
+ const DefaultSlot &a_slot) = 0;
+
virtual void set_breakpoint (const common::Loc &a_loc,
const UString &a_condition,
gint a_ignore_count,
@@ -1151,6 +1160,10 @@ public:
const UString &a_cookie = "") = 0;
virtual void enable_breakpoint (gint a_break_num,
+ const BreakpointsSlot &a_slot,
+ const UString &a_cookie="") = 0;
+
+ virtual void enable_breakpoint (gint a_break_num,
const UString &a_cookie="") = 0;
virtual void disable_breakpoint (gint a_break_num,
diff --git a/src/persp/dbgperspective/Makefile.am b/src/persp/dbgperspective/Makefile.am
index 75f7690..618f146 100644
--- a/src/persp/dbgperspective/Makefile.am
+++ b/src/persp/dbgperspective/Makefile.am
@@ -65,7 +65,9 @@ $(h)/nmv-dbg-perspective.h \
$(h)/nmv-vars-treeview.h \
$(h)/nmv-vars-treeview.cc \
$(h)/nmv-call-function-dialog.h \
-$(h)/nmv-call-function-dialog.cc
+$(h)/nmv-call-function-dialog.cc \
+$(h)/nmv-set-jump-to-dialog.h \
+$(h)/nmv-set-jump-to-dialog.cc
if BUILD_MEMORYVIEW
memoryview_sources = \
diff --git a/src/persp/dbgperspective/menus/menus.xml b/src/persp/dbgperspective/menus/menus.xml
index 8653782..a771d65 100644
--- a/src/persp/dbgperspective/menus/menus.xml
+++ b/src/persp/dbgperspective/menus/menus.xml
@@ -63,9 +63,12 @@
<menuitem action="NextMenuItemAction" name="NextMenuItem"/>
<menuitem action="StepMenuItemAction" name="StepMenuItem"/>
<menuitem action="StepOutMenuItemAction" name="StepOutMenuItem"/>
- <menuitem action="StepInAsmMenuItemAction" name="StepInAsmMenuItem"/>
+ <menuitem action="StepInAsmMenuItemAction"
+ name="StepInAsmMenuItem"/>
<menuitem action="StepOverAsmMenuItemAction"
name="StepOverAsmMenuItem"/>
+ <menuitem action="JumpToLocationMenuItemAction"
+ name="JumpToLocationMenuItem"/>
<separator/>
<menuitem action="ToggleBreakpointMenuItemAction"
name="ToggleBreakMenuItem"/>
diff --git a/src/persp/dbgperspective/nmv-dbg-perspective.cc b/src/persp/dbgperspective/nmv-dbg-perspective.cc
index 0b27e98..0c9575b 100644
--- a/src/persp/dbgperspective/nmv-dbg-perspective.cc
+++ b/src/persp/dbgperspective/nmv-dbg-perspective.cc
@@ -64,6 +64,7 @@
#include "common/nmv-date-utils.h"
#include "common/nmv-str-utils.h"
#include "common/nmv-address.h"
+#include "common/nmv-loc.h"
#include "nmv-sess-mgr.h"
#include "nmv-dbg-perspective.h"
#include "nmv-source-editor.h"
@@ -99,9 +100,11 @@
#endif // WITH_MEMORYVIEW
#include "nmv-watchpoint-dialog.h"
#include "nmv-debugger-utils.h"
+#include "nmv-set-jump-to-dialog.h"
using namespace std;
using namespace nemiver::common;
+using namespace nemiver::debugger_utils;
using namespace nemiver::ui_utils;
using namespace gtksourceview;
@@ -236,6 +239,12 @@ private:
void on_step_over_asm_action ();
void on_continue_action ();
void on_continue_until_action ();
+ void on_jump_to_location_action ();
+ void on_jump_to_current_location_action ();
+ void on_jump_and_break_to_current_location_action ();
+ void on_break_before_jump (const std::pair<int,
+ const IDebugger::Breakpoint&>&,
+ const Loc &a_loc);
void on_set_breakpoint_action ();
void on_set_breakpoint_using_dialog_action ();
void on_set_watchpoint_using_dialog_action ();
@@ -600,6 +609,12 @@ public:
void step_over_asm ();
void do_continue ();
void do_continue_until ();
+ void do_jump_to_current_location ();
+ void do_jump_and_break_to_location (const Loc&);
+ void do_jump_and_break_to_current_location ();
+ void jump_to_location (const map<int, IDebugger::Breakpoint>&,
+ const Loc &);
+ void jump_to_location_from_dialog (const SetJumpToDialog &);
void set_breakpoint_at_current_line_using_dialog ();
void set_breakpoint ();
void set_breakpoint (const UString &a_file,
@@ -616,9 +631,9 @@ public:
void append_breakpoints
(const map<int, IDebugger::Breakpoint> &a_breaks);
+ const IDebugger::Breakpoint* get_breakpoint (const Loc&) const;
const IDebugger::Breakpoint* get_breakpoint (const UString &a_file_name,
int a_linenum) const;
-
const IDebugger::Breakpoint* get_breakpoint (const Address &) const;
bool delete_breakpoint ();
@@ -626,10 +641,12 @@ public:
bool delete_breakpoint (const UString &a_file_path,
int a_linenum);
bool delete_breakpoint (const Address &a_address);
+ bool is_breakpoint_set_at_location (const Loc&, bool&);
bool is_breakpoint_set_at_line (const UString &a_file_path,
int a_linenum,
bool &a_enabled);
- bool is_breakpoint_set_at_address (const Address &);
+ bool is_breakpoint_set_at_address (const Address &,
+ bool&);
void toggle_breakpoint (const UString &a_file_path,
int a_linenum);
void toggle_breakpoint (const Address &a_address);
@@ -1010,7 +1027,6 @@ struct DBGPerspective::Priv {
list<UString> call_expr_history;
list<UString> var_inspector_dialog_history;
-
Priv () :
initialized (false),
reused_session (false),
@@ -1546,6 +1562,94 @@ DBGPerspective::on_continue_until_action ()
NEMIVER_CATCH
}
+/// This function is called when the user activates the action
+/// "JumpToLocationMenuItemAction". You can Look at
+/// DBGPerspective::init_actions to see how it is defined. It
+/// basically lets the user choose the location where she wants to
+/// jump to, and instruct IDebugger to jump there.
+void
+DBGPerspective::on_jump_to_location_action ()
+{
+ SetJumpToDialog dialog (plugin_path ());
+
+ SourceEditor *editor = get_current_source_editor ();
+
+ // If the user has selected a current location (possibly to jump
+ // to), then pre-fill the dialog with that location.
+ SafePtr<const Loc> cur_loc;
+ if (editor)
+ cur_loc.reset (editor->current_location ());
+ if (cur_loc)
+ dialog.set_location (*cur_loc);
+
+ // By default, set a breakpoint to the location we are jumping to,
+ // so that execution stops after the jump.
+ dialog.set_break_at_location (true);
+
+ // Now run the dialog and if the user hit anything but the OK
+ // button a the end, consider that she wants to cancel this
+ // procedure.
+ int result = dialog.run ();
+ if (result != Gtk::RESPONSE_OK)
+ return;
+
+ // By now we should have a proper location to jump to, so really
+ // perfom the jumping.
+ jump_to_location_from_dialog (dialog);
+}
+
+/// Callback function invoked when the menu item action "jump to
+/// current location" is activated.
+///
+/// It jumps to the location selected by the user in the source
+/// editor.
+void
+DBGPerspective::on_jump_to_current_location_action ()
+{
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+ NEMIVER_TRY
+ do_jump_to_current_location ();
+ NEMIVER_CATCH
+}
+
+/// Callback function invoked when the menu item action "setting a
+/// breakpoint to current lcoation and jump here" is activated.
+///
+/// It sets a breakpoint to the current location and jumps here. So
+/// is transfered to the location selected by the user in the source
+/// editor and is stopped there.
+void
+DBGPerspective::on_jump_and_break_to_current_location_action ()
+{
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+ NEMIVER_TRY
+ do_jump_and_break_to_current_location ();
+ NEMIVER_CATCH
+}
+
+/// This callback is invoked right after a breakpoint is set as part
+/// of a "set a breakpoint and jump there" process.
+///
+/// So this function jumps to the position given in parameter.
+///
+/// \param a_loc the location to jump to. This is also the location
+/// of the breakpoint that was set previously and which triggered this
+/// callback.
+void
+DBGPerspective::on_break_before_jump
+(const std::pair<int,
+ const IDebugger::Breakpoint&> &,
+ const Loc &a_loc)
+{
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+ NEMIVER_TRY;
+ debugger ()->jump_to_position (a_loc, &null_default_slot);
+ NEMIVER_CATCH;
+}
+
void
DBGPerspective::on_toggle_breakpoint_action ()
{
@@ -2520,6 +2624,13 @@ DBGPerspective::on_debugger_command_done_signal (const UString &a_command,
NEMIVER_CATCH
}
+/// Callback function invoked once a breakpoint was set.
+///
+/// \param a_breaks the list of all breakpoints currently set in the inferior.
+///
+/// \param a_cookie a string passed to the IDebugger::set_breakpoint
+/// call that triggered this callback.
+///
void
DBGPerspective::on_debugger_breakpoint_set_signal
(const std::pair<int, const IDebugger::Breakpoint&> &a,
@@ -2542,9 +2653,9 @@ DBGPerspective::on_debugger_breakpoints_list_signal
// When the breakpoint is set, it
// will send a 'cookie' along of the form
// "initiallly-disabled#filename.cc#123"
- if (a_cookie.find("initially-disabled") != UString::npos) {
- UString::size_type start_of_file = a_cookie.find('#') + 1;
- UString::size_type start_of_line = a_cookie.rfind('#') + 1;
+ if (a_cookie.find ("initially-disabled") != UString::npos) {
+ UString::size_type start_of_file = a_cookie.find ('#') + 1;
+ UString::size_type start_of_line = a_cookie.rfind ('#') + 1;
UString file = a_cookie.substr (start_of_file,
(start_of_line - 1) - start_of_file);
int line = atoi
@@ -3401,6 +3512,39 @@ DBGPerspective::init_actions ()
false
},
{
+ "JumpToCurrentLocationMenuItemAction",
+ nil_stock_id,
+ _("Jump to cursor"),
+ _("Jump to the currently selected line"),
+ sigc::mem_fun (*this, &DBGPerspective::on_jump_to_current_location_action),
+ ActionEntry::DEFAULT,
+ "",
+ false
+ },
+ {
+ "JumpAndBreakToCurrentLocationMenuItemAction",
+ nil_stock_id,
+ _("Jump and stop to cursor"),
+ _("Sets a breakpoint to the current currently selected line and jump there"),
+ sigc::mem_fun (*this,
+ &DBGPerspective::on_jump_and_break_to_current_location_action),
+ ActionEntry::DEFAULT,
+ "",
+ false
+ },
+ {
+ "JumpToLocationMenuItemAction",
+ nil_stock_id,
+ _("Jump to a given location"),
+ _("Select a given code location and jump there"),
+ sigc::mem_fun
+ (*this,
+ &DBGPerspective::on_jump_to_location_action),
+ ActionEntry::DEFAULT,
+ "<control>J",
+ false
+ },
+ {
"ToggleBreakpointMenuItemAction",
nil_stock_id,
// Depending on the context we will want this string to be
@@ -4776,6 +4920,22 @@ DBGPerspective::get_contextual_menu ()
workbench ().get_ui_manager ()->add_ui
(m_priv->contextual_menu_merge_id,
"/ContextualMenu",
+ "JumpToCurrentLocationMenuItem",
+ "JumpToCurrentLocationMenuItemAction",
+ Gtk::UI_MANAGER_AUTO,
+ false);
+
+ workbench ().get_ui_manager ()->add_ui
+ (m_priv->contextual_menu_merge_id,
+ "/ContextualMenu",
+ "JumpAndBreakToCurrentLocationMenuItem",
+ "JumpAndBreakToCurrentLocationMenuItemAction",
+ Gtk::UI_MANAGER_AUTO,
+ false);
+
+ workbench ().get_ui_manager ()->add_ui
+ (m_priv->contextual_menu_merge_id,
+ "/ContextualMenu",
"StopMenuItem",
"StopMenuItemAction",
Gtk::UI_MANAGER_AUTO,
@@ -6711,6 +6871,157 @@ DBGPerspective::do_continue_until ()
debugger ()->continue_to_position (file_path, current_line);
}
+/// Jump (transfer execution of the inferior) to the location selected
+/// by the user in the source editor.
+void
+DBGPerspective::do_jump_to_current_location ()
+{
+ SourceEditor *editor = get_current_source_editor ();
+ THROW_IF_FAIL (editor);
+
+ int current_line = editor->current_line ();
+ UString file_path;
+ editor->get_file_name (file_path);
+ SourceLoc loc (file_path, current_line);
+ debugger ()->jump_to_position (loc, &null_default_slot);
+}
+
+/// Set a breakpoint to a given location and jump (transfer execution
+/// of the inferior) there.
+///
+/// \param a_location the location to set breakpoint and jump to
+void
+DBGPerspective::do_jump_and_break_to_location (const Loc &a_location)
+{
+#define JUMP_TO_LOC_AFTER_ENABLE_BP(LOC) \
+ debugger ()->enable_breakpoint \
+ (bp->number (), \
+ sigc::bind \
+ (sigc::mem_fun \
+ (*this, \
+ &DBGPerspective::jump_to_location), \
+ (LOC)));
+
+#define JUMP_TO_LOC_AFTER_SET_BP(LOC) \
+ debugger ()->set_breakpoint \
+ (a_location, \
+ /*a_condition=*/"",/*a_ignore_count=*/0, \
+ sigc::bind \
+ (sigc::mem_fun \
+ (*this, \
+ &DBGPerspective::on_break_before_jump), \
+ (LOC)));
+
+ bool bp_enabled = false;
+ if (is_breakpoint_set_at_location (a_location,
+ bp_enabled)) {
+ if (bp_enabled) {
+ debugger ()->jump_to_position (a_location,
+ &null_default_slot);
+ } else {
+ const IDebugger::Breakpoint *bp =
+ get_breakpoint (a_location);
+ THROW_IF_FAIL (bp);
+
+ switch (a_location.kind ()) {
+ case Loc::UNDEFINED_LOC_KIND:
+ THROW ("Should not be reached");
+
+ case Loc::SOURCE_LOC_KIND: {
+ SourceLoc loc
+ (static_cast<const SourceLoc &> (a_location));
+ JUMP_TO_LOC_AFTER_ENABLE_BP (loc);
+ }
+ break;
+ case Loc::FUNCTION_LOC_KIND: {
+ FunctionLoc loc
+ (static_cast<const FunctionLoc &> (a_location));
+ JUMP_TO_LOC_AFTER_ENABLE_BP (loc);
+ }
+ break;
+ case Loc::ADDRESS_LOC_KIND: {
+ AddressLoc loc
+ (static_cast<const AddressLoc &> (a_location));
+ JUMP_TO_LOC_AFTER_ENABLE_BP (loc);
+ }
+ break;
+ }
+ }
+ } else {
+ switch (a_location.kind ()) {
+ case Loc::UNDEFINED_LOC_KIND:
+ THROW ("Should not be reached");
+
+ case Loc::SOURCE_LOC_KIND: {
+ SourceLoc loc
+ (static_cast<const SourceLoc &> (a_location));
+ JUMP_TO_LOC_AFTER_SET_BP (loc);
+ }
+ break;
+ case Loc::FUNCTION_LOC_KIND: {
+ FunctionLoc loc
+ (static_cast<const FunctionLoc &> (a_location));
+ JUMP_TO_LOC_AFTER_SET_BP (loc);
+ }
+ break;
+ case Loc::ADDRESS_LOC_KIND: {
+ AddressLoc loc
+ (static_cast<const AddressLoc &> (a_location));
+ JUMP_TO_LOC_AFTER_SET_BP (loc);
+ }
+ break;
+ }
+ }
+}
+
+/// Set a breakpoint to the location selected by the user in the
+/// source editor and jump (transfer execution of the inferior) there.
+void
+DBGPerspective::do_jump_and_break_to_current_location ()
+{
+ THROW_IF_FAIL (m_priv);
+ SourceEditor *editor = get_current_source_editor ();
+ THROW_IF_FAIL (editor);
+
+ SafePtr<const Loc> loc (editor->current_location ());
+ if (!loc) {
+ LOG_DD ("Got an empty location. Getting out.");
+ return;
+ }
+ do_jump_and_break_to_location (*loc);
+}
+
+/// Jump (transfert execution of the inferior) to a given source
+/// location. This is a callback for the
+/// IDebugger::breakpoint_set_signal signal.
+///
+/// \param a_loc the location to jump to.
+void
+DBGPerspective::jump_to_location (const map<int, IDebugger::Breakpoint>&,
+ const Loc &a_loc)
+{
+ debugger ()->jump_to_position (a_loc, &null_default_slot);
+}
+
+/// Jump (transfert execution of the inferior) to a given location
+/// that is specified by a dialog. The dialog must have filled by the
+/// user prior to calling this function.
+///
+/// \param a_dialog the dialog that contains the location specified by
+/// the user.
+void
+DBGPerspective::jump_to_location_from_dialog (const SetJumpToDialog &a_dialog)
+{
+ SafePtr<const Loc> location (a_dialog.get_location ());
+ if (!location
+ || location->kind ()== Loc::UNDEFINED_LOC_KIND)
+ return;
+ if (a_dialog.get_break_at_location ())
+ do_jump_and_break_to_location (*location);
+ else
+ debugger ()->jump_to_position (*location, &null_default_slot);
+}
+
void
DBGPerspective::set_breakpoint ()
{
@@ -6893,6 +7204,39 @@ DBGPerspective::append_breakpoints
append_breakpoint (iter->second);
}
+/// Return the breakpoint that was set at a given location.
+///
+/// \param a_location the location to consider
+///
+/// \return the breakpoint found at the given location, 0 if none was
+/// found.
+const IDebugger::Breakpoint*
+DBGPerspective::get_breakpoint (const Loc &a_location) const
+{
+ switch (a_location.kind ()) {
+ case Loc::UNDEFINED_LOC_KIND:
+ return false;
+ case Loc::SOURCE_LOC_KIND: {
+ const SourceLoc &loc =
+ static_cast<const SourceLoc&> (a_location);
+ return get_breakpoint (loc.file_path (), loc.line_number ());
+ }
+ case Loc::FUNCTION_LOC_KIND: {
+ // TODO: For now we cannot get a breakpoint set by function.
+ // For that we would need to be able to get the address at
+ // which a breakpoint set by function would be set to.
+ return false;
+ }
+ case Loc::ADDRESS_LOC_KIND: {
+ const AddressLoc &loc =
+ static_cast<const AddressLoc&> (a_location);
+ return get_breakpoint (loc.address ());
+ }
+ }
+ // Should not be reached.
+ return 0;
+}
+
const IDebugger::Breakpoint*
DBGPerspective::get_breakpoint (const UString &a_file_name,
int a_line_num) const
@@ -7282,6 +7626,52 @@ DBGPerspective::delete_breakpoint (const Address &a_address)
return delete_breakpoint (bp->number ());
}
+/// Return true if a breakpoint was set at a given location.
+///
+/// \param a_location the location to consider
+///
+/// \return true if there was a breakpoint set at the given location
+bool
+DBGPerspective::is_breakpoint_set_at_location (const Loc &a_location,
+ bool &a_enabled)
+{
+ switch (a_location.kind ()) {
+ case Loc::UNDEFINED_LOC_KIND:
+ return false;
+ case Loc::SOURCE_LOC_KIND: {
+ const SourceLoc &loc =
+ static_cast<const SourceLoc&> (a_location);
+ return is_breakpoint_set_at_line (loc.file_path (),
+ loc.line_number (),
+ a_enabled);
+ }
+ break;
+ case Loc::FUNCTION_LOC_KIND:
+ // Grrr, for now we cannot know if a breakpoint was set at a
+ // function's entry point.
+ return false;
+ break;
+ case Loc::ADDRESS_LOC_KIND: {
+ const AddressLoc &loc =
+ static_cast<const AddressLoc&> (a_location);
+ return is_breakpoint_set_at_address (loc.address (),
+ a_enabled);
+ }
+ break;
+ }
+ // Should not be reached
+ return false;
+}
+
+/// Test whether if a breakpoint was set at a source location.
+///
+/// \param a_file_path the path of the file to consider
+///
+/// \param a_line_num the line number of the location to consider
+///
+/// \param a_enabled iff the function returns true, this boolean is
+/// set. It's value is then either true if the breakpoint found at
+/// the given source location is enabled, false otherwise.
bool
DBGPerspective::is_breakpoint_set_at_line (const UString &a_file_path,
int a_line_num,
@@ -7295,12 +7685,25 @@ DBGPerspective::is_breakpoint_set_at_line (const UString &a_file_path,
return false;
}
+/// Test whether if a breakpoint was set at a given address.
+///
+/// \param a_address the address to consider.
+///
+/// \param a_enabled iff the function returns true, this boolean is
+/// set. It's value is then either true if the breakpoint found at
+/// the given address is enabled, false otherwise.
+///
+/// \return true if a breakpoint is set at the given address, false
+/// otherwise.
bool
-DBGPerspective::is_breakpoint_set_at_address (const Address &a_address)
+DBGPerspective::is_breakpoint_set_at_address (const Address &a_address,
+ bool &a_enabled)
{
const IDebugger::Breakpoint *bp;
- if ((bp = get_breakpoint (a_address)) != 0)
+ if ((bp = get_breakpoint (a_address)) != 0) {
+ a_enabled = bp->enabled ();
return true;
+ }
return false;
}
@@ -7327,7 +7730,8 @@ void
DBGPerspective::toggle_breakpoint (const Address &a_address)
{
LOG_FUNCTION_SCOPE_NORMAL_DD;
- if (is_breakpoint_set_at_address (a_address)) {
+ bool enabled = false;
+ if (is_breakpoint_set_at_address (a_address, enabled)) {
delete_breakpoint (a_address);
} else {
set_breakpoint (a_address, /*is_count_point=*/false);
diff --git a/src/persp/dbgperspective/nmv-set-jump-to-dialog.cc b/src/persp/dbgperspective/nmv-set-jump-to-dialog.cc
new file mode 100644
index 0000000..b67ac1d
--- /dev/null
+++ b/src/persp/dbgperspective/nmv-set-jump-to-dialog.cc
@@ -0,0 +1,428 @@
+/*
+ *This file is part of the Nemiver project
+ *
+ *Nemiver is free software; you can redistribute
+ *it and/or modify it under the terms of
+ *the GNU General Public License as published by the
+ *Free Software Foundation; either version 2,
+ *or (at your option) any later version.
+ *
+ *Nemiver is distributed in the hope that it will
+ *be useful, but WITHOUT ANY WARRANTY;
+ *without even the implied warranty of
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *See the GNU General Public License for more details.
+ *
+ *You should have received a copy of the
+ *GNU General Public License along with Nemiver;
+ *see the file COPYING.
+ *If not, write to the Free Software Foundation,
+ *Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *See COPYRIGHT file copyright information.
+ */
+#include <glib/gi18n.h>
+#include <sstream>
+#include "common/nmv-loc.h"
+#include "common/nmv-str-utils.h"
+#include "nmv-set-jump-to-dialog.h"
+#include "nmv-ui-utils.h"
+
+
+using namespace nemiver::common;
+using namespace nemiver::ui_utils;
+
+NEMIVER_BEGIN_NAMESPACE (nemiver)
+
+class SetJumpToDialog::Priv
+{
+public:
+ Gtk::Entry *entry_function;
+ Gtk::Entry *entry_filename;
+ Gtk::Entry *entry_line;
+ Gtk::Entry *entry_address;
+ Gtk::RadioButton *radio_function_name;
+ Gtk::RadioButton *radio_source_location;
+ Gtk::RadioButton *radio_binary_location;
+ Gtk::CheckButton *check_break_at_destination;
+ Gtk::Button *okbutton;
+
+ enum Mode
+ {
+ MODE_UNDEFINED = 0,
+ MODE_FUNCTION_NAME_LOCATION,
+ MODE_SOURCE_LOCATION,
+ MODE_BINARY_LOCATION
+ };
+
+ Priv (Gtk::Dialog &a_dialog,
+ const Glib::RefPtr<Gtk::Builder> &a_builder)
+ : entry_function (0),
+ entry_filename (0),
+ entry_line (0),
+ entry_address (0),
+ radio_function_name (0),
+ radio_source_location (0),
+ radio_binary_location (0),
+ check_break_at_destination (0),
+ okbutton (0)
+ {
+ a_dialog.set_default_response (Gtk::RESPONSE_OK);
+
+ entry_function =
+ get_widget_from_gtkbuilder<Gtk::Entry> (a_builder,
+ "functionentry");
+ THROW_IF_FAIL (entry_function);
+ entry_function->signal_changed ().connect
+ (sigc::mem_fun (*this, &Priv::on_text_changed_signal));
+
+ entry_filename =
+ get_widget_from_gtkbuilder<Gtk::Entry> (a_builder,
+ "filenameentry");
+ THROW_IF_FAIL (entry_filename);
+ entry_filename->signal_changed ().connect
+ (sigc::mem_fun (*this, &Priv::on_text_changed_signal));
+
+ entry_line =
+ get_widget_from_gtkbuilder<Gtk::Entry> (a_builder,
+ "lineentry");
+ THROW_IF_FAIL (entry_line);
+ entry_line->signal_changed ().connect
+ (sigc::mem_fun (*this, &Priv::on_text_changed_signal));
+
+ entry_address =
+ get_widget_from_gtkbuilder<Gtk::Entry> (a_builder,
+ "addressentry");
+ THROW_IF_FAIL (entry_address);
+ entry_address->signal_changed ().connect
+ (sigc::mem_fun (*this, &Priv::on_text_changed_signal));
+
+ radio_function_name =
+ get_widget_from_gtkbuilder<Gtk::RadioButton>
+ (a_builder, "functionnameradio");
+ THROW_IF_FAIL (radio_function_name);
+ radio_function_name->signal_clicked ().connect
+ (sigc::mem_fun (*this, &Priv::on_radiobutton_changed));
+
+ radio_source_location =
+ get_widget_from_gtkbuilder<Gtk::RadioButton>
+ (a_builder, "sourcelocationradio");
+ THROW_IF_FAIL (radio_source_location);
+ radio_source_location->signal_clicked ().connect
+ (sigc::mem_fun (*this, &Priv::on_radiobutton_changed));
+
+ radio_binary_location =
+ get_widget_from_gtkbuilder<Gtk::RadioButton>
+ (a_builder, "binarylocationradio");
+ THROW_IF_FAIL (radio_binary_location);
+ radio_binary_location->signal_clicked ().connect
+ (sigc::mem_fun (*this, &Priv::on_radiobutton_changed));
+
+ check_break_at_destination =
+ get_widget_from_gtkbuilder<Gtk::CheckButton>
+ (a_builder, "breakatdestinationcheck");
+ THROW_IF_FAIL (check_break_at_destination);
+
+ okbutton =
+ get_widget_from_gtkbuilder<Gtk::Button>
+ (a_builder, "okbutton");
+ THROW_IF_FAIL (okbutton);
+ }
+
+ /// Return the 'location setting mode' of the dialog. I.e, it can
+ /// set either function name, source or binary address locations,
+ /// depending on the radio button that got selected by the user.
+ ///
+ /// \return the 'location setting mode' radio button selected by
+ /// the user.
+ Mode
+ mode () const
+ {
+ if (radio_function_name->get_active ())
+ return MODE_FUNCTION_NAME_LOCATION;
+ else if (radio_source_location->get_active ())
+ return MODE_SOURCE_LOCATION;
+ else if (radio_binary_location->get_active ())
+ return MODE_BINARY_LOCATION;
+ else
+ return MODE_UNDEFINED;
+ }
+
+ /// Set the 'location setting mode' of the dialog.
+ ///
+ /// \param a_mode the new mode to set.
+ void
+ mode (Mode a_mode)
+ {
+ switch (a_mode) {
+ case MODE_UNDEFINED:
+ THROW ("Unreachable code reached");
+ break;
+ case MODE_FUNCTION_NAME_LOCATION:
+ radio_function_name->set_active ();
+ break;
+ case MODE_SOURCE_LOCATION:
+ radio_source_location->set_active ();
+ break;
+ case MODE_BINARY_LOCATION:
+ radio_binary_location->set_active ();
+ break;
+ }
+ }
+
+ /// Return the location selected by the user using this dialog.
+ /// This is a pointer that needs to deleted by the caller.
+ ///
+ /// \return a pointer to the location selected by the user of the
+ /// dialog. Must be deleted by the caller using the delete
+ /// operator.
+ Loc*
+ get_location () const
+ {
+ const Mode m = mode ();
+ switch (m) {
+ case MODE_UNDEFINED:
+ THROW ("Unreachable code reached");
+ break;
+ case MODE_FUNCTION_NAME_LOCATION: {
+ FunctionLoc *loc =
+ new FunctionLoc (entry_function->get_text ());
+ return loc;
+ }
+ case MODE_SOURCE_LOCATION: {
+ std::string path, line;
+ if (get_file_path_and_line_num (path, line)) {
+ SourceLoc *loc =
+ new SourceLoc (path, atoi (line.c_str ()));
+ return loc;
+ }
+ }
+ break;
+ case MODE_BINARY_LOCATION: {
+ Address a (entry_address->get_text ());
+ AddressLoc *loc = new AddressLoc (a);
+ return loc;
+ }
+ } // end case
+
+ return 0;
+ }
+
+ /// Set a location in the dialog. Depending on the type of
+ /// location, this function will Do The Right Thing, e.g,
+ /// selecting the right radio button etc
+ void
+ set_location (const Loc &a_loc)
+ {
+ switch (a_loc.kind ()) {
+ case Loc::UNDEFINED_LOC_KIND:
+ break;
+ case Loc::SOURCE_LOC_KIND: {
+ const SourceLoc &loc = static_cast<const SourceLoc&> (a_loc);
+ mode (MODE_SOURCE_LOCATION);
+ entry_filename->set_text (loc.file_path ());
+ std::ostringstream o;
+ o << loc.line_number ();
+ entry_line->set_text (o.str ());
+ }
+ break;
+ case Loc::FUNCTION_LOC_KIND: {
+ const FunctionLoc &loc = static_cast<const FunctionLoc&> (a_loc);
+ mode (MODE_FUNCTION_NAME_LOCATION);
+ entry_function->set_text (loc.function_name ());
+ }
+ break;
+ case Loc::ADDRESS_LOC_KIND: {
+ const AddressLoc &loc = static_cast<const AddressLoc&> (a_loc);
+ mode (MODE_BINARY_LOCATION);
+ std::ostringstream o;
+ o << loc.address ();
+ entry_address->set_text (o.str ());
+ }
+ break;
+ }
+ }
+
+ /// Set the checkbox which semantic is to set a breakpoint at the
+ /// jump location selected by the user.
+ ///
+ /// \param a boolean meaning whether to select the "break at
+ /// location" checkbox or not.
+ void
+ set_break_at_location (bool a)
+ {
+ check_break_at_destination->set_active (a);
+ }
+
+ /// Query whether the "break at location" checkbox is selected or
+ /// not.
+ ///
+ /// \return true if the "break at location" checkbox is selected,
+ /// false otherwise.
+ bool
+ get_break_at_location () const
+ {
+ return check_break_at_destination->get_active ();
+ }
+
+ /// Return the path/line number combo that the user entered in the
+ /// dialog, iff the dialog is in the "source location" mode.
+ ///
+ /// \param a_path the path of the source location. This is set
+ /// iff the function returns true.
+ ///
+ /// \param a_line_num a string representing the line number of the
+ /// source location. This is set iff the function returns true.
+ ///
+ /// \return true if the dialog is in source location mode and if
+ /// the user entered a file path or line number.
+ bool
+ get_file_path_and_line_num (std::string &a_path,
+ std::string &a_line_num) const
+ {
+ if (entry_line->get_text ().empty ()) {
+ // Try to see if entry_filename contains a location string
+ // of the form "filename:number".
+ return str_utils::extract_path_and_line_num_from_location
+ (entry_filename->get_text ().raw (), a_path, a_line_num);
+ } else {
+ // Try to just get the file path from the entry_filename
+ // and line from entry_line.
+ if (!entry_filename->get_text ().empty ()
+ && atoi (entry_line->get_text ().c_str ())) {
+ a_path = entry_filename->get_text ();
+ a_line_num = entry_line->get_text ().raw ();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /// Update the sensitivity of the OK button, depending on the
+ /// entries the user modified and what she typed in.
+ void
+ update_ok_button_sensitivity ()
+ {
+ THROW_IF_FAIL (entry_filename);
+ THROW_IF_FAIL (entry_line);
+ THROW_IF_FAIL (entry_function);
+ THROW_IF_FAIL (entry_address);
+ THROW_IF_FAIL (okbutton);
+
+ Mode m = mode ();
+ switch (m) {
+ case MODE_UNDEFINED:
+ break;
+ case MODE_SOURCE_LOCATION: {
+ string filename, line;
+ if (get_file_path_and_line_num (filename, line)
+ || atoi (entry_line->get_text ().c_str ()))
+ okbutton->set_sensitive (true);
+ else
+ okbutton->set_sensitive (false);
+ }
+ break;
+ case MODE_FUNCTION_NAME_LOCATION: {
+ if (!entry_function->get_text ().empty ())
+ okbutton->set_sensitive (true);
+ else
+ okbutton->set_sensitive (false);
+ }
+ break;
+ case MODE_BINARY_LOCATION: {
+ bool address_is_valid = false;
+ UString address = entry_address->get_text ();
+ // Validate the address
+ if (str_utils::string_is_number (address))
+ address_is_valid = true;
+ okbutton->set_sensitive (address_is_valid);
+ }
+ break;
+ default:
+ okbutton->set_sensitive (true);
+ break;
+ }
+ }
+
+ void
+ on_text_changed_signal ()
+ {
+ NEMIVER_TRY;
+
+ update_ok_button_sensitivity ();
+
+ NEMIVER_CATCH;
+ }
+
+ void
+ on_radiobutton_changed ()
+ {
+ NEMIVER_TRY;
+
+ Mode m = mode ();
+
+ entry_function->set_sensitive (m == MODE_FUNCTION_NAME_LOCATION);
+
+ entry_filename->set_sensitive (m == MODE_SOURCE_LOCATION);
+ entry_line->set_sensitive (m == MODE_SOURCE_LOCATION);
+
+ entry_address->set_sensitive (m == MODE_BINARY_LOCATION);
+
+ update_ok_button_sensitivity ();
+
+ NEMIVER_CATCH;
+ }
+};// end class SetJumpToDialog::Priv
+
+SetJumpToDialog::SetJumpToDialog (const UString &a_root_path)
+ : Dialog (a_root_path, "setjumptodialog.ui", "setjumptodialog")
+{
+ m_priv.reset (new Priv (widget (), gtkbuilder ()));
+}
+
+SetJumpToDialog::~SetJumpToDialog ()
+{
+}
+
+/// \return the location set by the user via the dialog
+const Loc*
+SetJumpToDialog::get_location () const
+{
+ THROW_IF_FAIL (m_priv);
+ return m_priv->get_location ();
+}
+
+/// Set the location proprosed by the dialog.
+///
+/// \param a_loc the new location to set
+void
+SetJumpToDialog::set_location (const Loc &a_loc)
+{
+ THROW_IF_FAIL (m_priv);
+
+ m_priv->set_location (a_loc);
+}
+
+/// Set or unset the "set break at location" check button
+///
+/// \param a if true, check the "set break at location" check button.
+/// Uncheck it otherwise.
+void
+SetJumpToDialog::set_break_at_location (bool a)
+{
+ THROW_IF_FAIL (m_priv);
+ m_priv->set_break_at_location (a);
+}
+
+/// Get the value of the "set break at location" check button.
+///
+/// \return true if the "set break at location" check button is
+/// checked, false otherwise.
+bool
+SetJumpToDialog::get_break_at_location () const
+{
+ THROW_IF_FAIL (m_priv);
+ return m_priv->get_break_at_location ();
+}
+
+NEMIVER_END_NAMESPACE (nemiver)
diff --git a/src/persp/dbgperspective/nmv-set-jump-to-dialog.h b/src/persp/dbgperspective/nmv-set-jump-to-dialog.h
new file mode 100644
index 0000000..a5b627f
--- /dev/null
+++ b/src/persp/dbgperspective/nmv-set-jump-to-dialog.h
@@ -0,0 +1,57 @@
+//Author: Dodji Seketeli
+/*
+ *This file is part of the Nemiver project
+ *
+ *Nemiver is free software; you can redistribute
+ *it and/or modify it under the terms of
+ *the GNU General Public License as published by the
+ *Free Software Foundation; either version 2,
+ *or (at your option) any later version.
+ *
+ *Nemiver is distributed in the hope that it will
+ *be useful, but WITHOUT ANY WARRANTY;
+ *without even the implied warranty of
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *See the GNU General Public License for more details.
+ *
+ *You should have received a copy of the
+ *GNU General Public License along with Nemiver;
+ *see the file COPYING.
+ *If not, write to the Free Software Foundation,
+ *Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *See COPYRIGHT file copyright information.
+ */
+
+#ifndef __NEMIVER_SET_JUMP_TO_DIALOG_H__
+#define __NEMIVER_SET_JUMP_TO_DIALOG_H__
+
+#include "common/nmv-safe-ptr-utils.h"
+#include "nmv-dialog.h"
+
+NEMIVER_BEGIN_NAMESPACE (nemiver)
+
+namespace common {
+ class UString;
+ class Loc;
+}
+
+class SetJumpToDialog : public Dialog
+{
+ class Priv;
+ SafePtr<Priv> m_priv;
+
+ public:
+
+ SetJumpToDialog (const UString &a_resource_root_path);
+ virtual ~SetJumpToDialog ();
+
+ const common::Loc* get_location () const;
+ void set_location (const common::Loc&);
+ void set_break_at_location (bool);
+ bool get_break_at_location () const;
+};
+
+NEMIVER_END_NAMESPACE (nemiver)
+
+#endif // __NEMIVER_JUMP_TO_DIALOG_H__
diff --git a/src/persp/dbgperspective/ui/Makefile.am b/src/persp/dbgperspective/ui/Makefile.am
index 496ce3a..2b42c3f 100644
--- a/src/persp/dbgperspective/ui/Makefile.am
+++ b/src/persp/dbgperspective/ui/Makefile.am
@@ -13,7 +13,8 @@ chooseoverloadsdialog.ui \
remotetargetdialog.ui \
globalvarsinspector.ui \
callfunctiondialog.ui \
-watchpointdialog.ui
+watchpointdialog.ui \
+setjumptodialog.ui
uidir = @NEMIVER_PLUGINS_DIR@/$(PLUGIN_NAME)/ui
ui_DATA = $(uifiles)
diff --git a/src/persp/dbgperspective/ui/setjumptodialog.ui b/src/persp/dbgperspective/ui/setjumptodialog.ui
new file mode 100644
index 0000000..203ff02
--- /dev/null
+++ b/src/persp/dbgperspective/ui/setjumptodialog.ui
@@ -0,0 +1,281 @@
+<?xml version="1.0"?>
+<interface>
+ <requires lib="gtk+" version="2.16"/>
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkDialog" id="setjumptodialog">
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">Set location to jump to</property>
+ <property name="window_position">center-on-parent</property>
+ <property name="default_width">300</property>
+ <property name="type_hint">dialog</property>
+ <property name="gravity">center</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <object class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child>
+ <object class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes"><b>Jump to location:</b></property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkTable" id="table1">
+ <property name="visible">True</property>
+ <property name="n_rows">8</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkRadioButton" id="functionnameradio">
+ <property name="label" translatable="yes">F_unction Name:</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="sourcelocationradio">
+ <property name="label" translatable="yes">_Source Location:</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">functionnameradio</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="binarylocationradio">
+ <property name="label" translatable="yes">_Binary Location:</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">functionnameradio</property>
+ </object>
+ <packing>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Function:</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">File name:</property>
+ </object>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Line:</property>
+ </object>
+ <packing>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Address:</property>
+ </object>
+ <packing>
+ <property name="top_attach">6</property>
+ <property name="bottom_attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="functionentry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="filenameentry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="lineentry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="addressentry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">6</property>
+ <property name="bottom_attach">7</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="breakatdestinationcheck">
+ <property name="label" translatable="yes">Break at destination</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">7</property>
+ <property name="bottom_attach">8</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <object class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="cancelbutton">
+ <property name="label">gtk-cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="okbutton">
+ <property name="label">gtk-ok</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-6">cancelbutton</action-widget>
+ <action-widget response="-5">okbutton</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/src/uicommon/nmv-source-editor.cc b/src/uicommon/nmv-source-editor.cc
index e3d6206..d27fe37 100644
--- a/src/uicommon/nmv-source-editor.cc
+++ b/src/uicommon/nmv-source-editor.cc
@@ -867,6 +867,37 @@ SourceEditor::current_column (int &a_col)
m_priv->non_asm_ctxt.current_column = a_col;
}
+/// Return a pointer to the current location selected by the user.
+///
+/// \return a pointer to an instance of Loc representing the location
+/// selected by the user. If the user hasn't selected any location,
+/// then return 0.
+const Loc*
+SourceEditor::current_location () const
+{
+ BufferType type = get_buffer_type ();
+ switch (type) {
+ case BUFFER_TYPE_UNDEFINED:
+ break;
+ case BUFFER_TYPE_SOURCE: {
+ UString path;
+ get_path (path);
+ THROW_IF_FAIL (!path.empty ());
+ if (current_line () >= 0)
+ return new SourceLoc (path, current_line ());
+ }
+ break;
+ case BUFFER_TYPE_ASSEMBLY: {
+ Address a;
+ if (current_address (a))
+ return new AddressLoc (a);
+ }
+ break;
+ }
+
+ return 0;
+}
+
bool
SourceEditor::move_where_marker_to_line (int a_line, bool a_do_scroll)
{
diff --git a/src/uicommon/nmv-source-editor.h b/src/uicommon/nmv-source-editor.h
index bbf1442..13132e6 100644
--- a/src/uicommon/nmv-source-editor.h
+++ b/src/uicommon/nmv-source-editor.h
@@ -35,6 +35,7 @@
#include "common/nmv-address.h"
#include "common/nmv-range.h"
#include "common/nmv-asm-instr.h"
+#include "common/nmv-loc.h"
using gtksourceview::SourceView;
using gtksourceview::SourceBuffer;
@@ -42,6 +43,7 @@ using Gtk::VBox;
using nemiver::common::SafePtr;
using nemiver::common::UString;
using nemiver::common::Address;
+using nemiver::common::Loc;
using std::list;
using std::map;
@@ -82,6 +84,7 @@ public:
int current_line () const;
void current_line (int a_line);
int current_column () const;
+ const Loc* current_location () const;
void current_column (int &a_col);
bool move_where_marker_to_line (int a_line, bool a_do_scroll = true);
void unset_where_marker ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]