[nemiver/asm-support] ASM <-> Source code switching preliminary support



commit fd2137dc6928ee68d8aeb5577a99620c16a26de4
Author: Dodji Seketeli <dodji redhat com>
Date:   Sun Mar 7 21:02:08 2010 +0100

    ASM <-> Source code switching preliminary support
    
    	Preliminary support to switch from source code view to assembly
    	view and backward. Neiher decorating nor stepping is supported
    	in the assembly view yet.
    	* src/uicommon/nmv-source-editor.h (clear_decorations): New
    	interface.
    	(SourceEditor::*): Renamed all methods that had "composite" in
    	their names into method that have "assembly" in their name
    	instead.
    	* src/uicommon/nmv-source-editor.cc (*):
    	Same similar renaming as above.
    	Go further by renaming members that have "comp" in their names
    	by members that have "asm" in their names instead.
    	(SourceEditor::clear_decorations): New definition.
    	* src/persp/dbgperspective/nmv-dbg-perspective.cc
    	(DBGPerspective::on_disassemble_action,
    	DBGPerspective::on_switch_to_disassembly_action,
    	DBGPerspective::on_debugger_disassembled_signal,
    	DBGPerspective::switch_to_disassembly,
    	DBGPerspective::switch_to_source_code,
    	DBGPerspective::disassemble,
    	DBGPerspective::find_absolute_path_or_ask_user,
    	DBGPerspective::remove_visual_decorations_from_text): New fns
    	declarations and definitions.
    	(DBGPerspective::find_absolute_path,
    	DBGPerspective::ask_user_to_select_file): Extract these
    	functions from DBGPerspective::append_visual_breakpoint.
    	(DBGPerspective::append_visual_breakpoint): Use the new
    	DBGPerspective::find_absolute_path and
    	DBGPerspective::ask_user_to_select_file.
    	(DBGPerspective::init_actions): Add menu actions DisAsmMenuItemAction,
    	SwitchToAsmMenuItemAction, SwitchToSourceMenuItemAction. Used
    	the new DBGPerspective::on_disassemble_action, and
    	DBGPerspective::switch_to_source_code as the callbacks for this
    	menu actions.
    	(DBGPerspective::open_disassembly): If the disassembly tab
    	exists already, re-use it.
    	(DBGPerspective::open_file): Don't yell if the file path is empty.
    	* src/persp/dbgperspective/menus/menus.xml: Add new "Show assembly",
    	"Switch to assembly" and "Switch to source" menu items to the
    	"debug" menu.

 src/persp/dbgperspective/menus/menus.xml        |    6 +
 src/persp/dbgperspective/nmv-dbg-perspective.cc |  433 +++++++++++++++++------
 src/uicommon/nmv-source-editor.cc               |  180 ++++++----
 src/uicommon/nmv-source-editor.h                |   29 +-
 4 files changed, 449 insertions(+), 199 deletions(-)
---
diff --git a/src/persp/dbgperspective/menus/menus.xml b/src/persp/dbgperspective/menus/menus.xml
index 75967c5..ccdb2f1 100644
--- a/src/persp/dbgperspective/menus/menus.xml
+++ b/src/persp/dbgperspective/menus/menus.xml
@@ -85,6 +85,12 @@
                 name="ActivateGlobalVariablesDialogMenuItem"/>
             <menuitem action="RefreshLocalVariablesMenuItemAction"
                 name="RefreshLocalVariablesMenuItemAction"/>
+            <menuitem action="DisAsmMenuItemAction"
+                name="DisAsmMenuItemAction"/>
+            <menuitem action="SwitchToAsmMenuItemAction"
+                name="SwitchToAsmMenuItemAction"/>
+            <menuitem action="SwitchToSourceMenuItemAction"
+                name="SwitchToSourceMenuItemAction"/>
         </menu>
     </placeholder>
   </menubar>
diff --git a/src/persp/dbgperspective/nmv-dbg-perspective.cc b/src/persp/dbgperspective/nmv-dbg-perspective.cc
index 63c65ae..ada68c5 100644
--- a/src/persp/dbgperspective/nmv-dbg-perspective.cc
+++ b/src/persp/dbgperspective/nmv-dbg-perspective.cc
@@ -132,6 +132,8 @@ const char *LAST_RUN_TIME= "lastruntime";
 const char *DBG_PERSPECTIVE_MOUSE_MOTION_DOMAIN =
                                 "dbg-perspective-mouse-motion-domain";
 
+static const int NUM_INSTR_TO_DISASSEMBLE = 20;
+
 const char* CONF_KEY_NEMIVER_SOURCE_DIRS =
                 "/apps/nemiver/dbgperspective/source-search-dirs";
 const char* CONF_KEY_SHOW_DBG_ERROR_DIALOGS =
@@ -279,6 +281,8 @@ private:
     void on_set_breakpoint_using_dialog_action ();
     void on_set_watchpoint_using_dialog_action ();
     void on_refresh_locals_action ();
+    void on_disassemble_action (bool a_show_asm_in_new_tab);
+    void on_switch_to_disassembly_action ();
     void on_toggle_breakpoint_action ();
     void on_toggle_breakpoint_enabled_action ();
     void on_inspect_variable_action ();
@@ -320,6 +324,7 @@ private:
 
     void on_insertion_changed_signal (const Gtk::TextBuffer::iterator& iter,
                                       SourceEditor *a_editor);
+
     void update_toggle_menu_text (const UString& a_current_file,
                                   int a_current_line);
 
@@ -339,7 +344,7 @@ private:
     void on_debugger_detached_from_target_signal ();
 
     void on_debugger_got_target_info_signal (int a_pid,
-                                           const UString &a_exe_path);
+                                             const UString &a_exe_path);
 
     void on_debugger_console_message_signal (const UString &a_msg);
 
@@ -386,6 +391,10 @@ private:
                                     (const UString &a_var_name,
                                      const IDebugger::VariableSafePtr &a_var,
                                      const UString &a_cooker);
+    void on_debugger_disassembled_signal
+                            (const IDebugger::DisassembleInfo &a_info,
+                             const std::list<IDebugger::AsmInstr> &a_instrs,
+                             bool a_show_asm_in_new_tab = true);
 
     void on_variable_created_for_tooltip_signal
                                     (const IDebugger::VariableSafePtr);
@@ -522,6 +531,11 @@ public:
     bool open_disassembly (const IDebugger::DisassembleInfo &a_info,
                            const std::list<IDebugger::AsmInstr> &a_asm);
 
+    void switch_to_disassembly (const IDebugger::DisassembleInfo &a_info,
+                                const std::list<IDebugger::AsmInstr> &a_asm);
+
+    void switch_to_source_code ();
+
     void close_opened_files ();
 
     void update_file_maps ();
@@ -605,6 +619,7 @@ public:
     void set_breakpoint_from_dialog (SetBreakpointDialog &a_dialog);
     void set_watchpoint_using_dialog ();
     void refresh_locals ();
+    void disassemble (bool a_show_asm_in_new_tab);
 
     void inspect_variable ();
     void inspect_variable (const UString &a_variable_name);
@@ -614,6 +629,12 @@ public:
     void toggle_breakpoint_enabled (const UString &a_file_path,
                                     int a_linenum);
     void toggle_breakpoint_enabled ();
+    bool find_absolute_path (const UString& a_file_path,
+                             UString& a_absolute_path);
+    bool find_absolute_path_or_ask_user (const UString& a_file_path,
+                                         UString& a_absolute_path);
+    bool ask_user_to_select_file (const UString &a_file_name,
+                                  UString& a_selected_file_path);
     bool append_visual_breakpoint (const UString &a_file_name,
                                    int a_linenum,
                                    UString &a_actual_file_name,
@@ -626,6 +647,7 @@ public:
     void choose_function_overload
                 (const vector<IDebugger::OverloadsChoiceEntry> &a_entries);
 
+    void remove_visual_decorations_from_text (const UString &a_file_path);
     bool apply_decorations_to_text (const UString &a_file_path);
 
     IDebuggerSafePtr& debugger ();
@@ -1492,6 +1514,23 @@ DBGPerspective::on_refresh_locals_action ()
 }
 
 void
+DBGPerspective::on_disassemble_action (bool a_show_asm_in_new_tab)
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+    NEMIVER_TRY
+    disassemble (a_show_asm_in_new_tab);
+    NEMIVER_CATCH
+}
+
+void
+DBGPerspective::on_switch_to_disassembly_action ()
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+    NEMIVER_TRY
+    NEMIVER_CATCH
+}
+
+void
 DBGPerspective::on_toggle_breakpoint_enabled_action ()
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
@@ -2520,6 +2559,20 @@ DBGPerspective::on_debugger_variable_value_signal
 }
 
 void
+DBGPerspective::on_debugger_disassembled_signal
+                            (const IDebugger::DisassembleInfo &a_info,
+                             const std::list<IDebugger::AsmInstr> &a_instrs,
+                             bool a_show_asm_in_new_tab)
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+    if (a_show_asm_in_new_tab)
+        open_disassembly (a_info, a_instrs);
+    else
+        switch_to_disassembly (a_info, a_instrs);
+}
+
+void
 DBGPerspective::on_variable_created_for_tooltip_signal
                                 (const IDebugger::VariableSafePtr a_var)
 {
@@ -3145,7 +3198,43 @@ DBGPerspective::init_actions ()
             ActionEntry::DEFAULT,
             "",
             false
-        }
+        },
+        {
+            "DisAsmMenuItemAction",
+            nil_stock_id,
+            _("Show assembly"),
+            _("Show the assembly code of the source code being "
+              "currently debugged, in another tab"),
+            sigc::bind (sigc::mem_fun
+                            (*this, &DBGPerspective::on_disassemble_action),
+                        /*show_asm_in_new_tab=*/true),
+            ActionEntry::DEFAULT,
+            "",
+            false
+        },
+        {
+            "SwitchToAsmMenuItemAction",
+            nil_stock_id,
+            _("Switch to assembly"),
+            _("Show the assembly code of the source code being "
+              "currently debugged"),
+            sigc::bind (sigc::mem_fun
+                            (*this, &DBGPerspective::on_disassemble_action),
+                        /*show_asm_in_new_tab=*/false),
+            ActionEntry::DEFAULT,
+            "",
+            false
+        },
+        {
+            "SwitchToSourceMenuItemAction",
+            nil_stock_id,
+            _("Switch to source"),
+            _("Show the source code being currently debugged"),
+            sigc::mem_fun (*this, &DBGPerspective::switch_to_source_code),
+            ActionEntry::DEFAULT,
+            "",
+            false
+        },
     };
 
     static ui_utils::ActionEntry s_debugger_busy_action_entries [] = {
@@ -3727,6 +3816,39 @@ DBGPerspective::clear_session_data ()
     m_priv->source_dirs.clear ();
 }
 
+bool
+DBGPerspective::find_absolute_path (const UString& a_file_path,
+                                    UString &a_absolute_path)
+{
+    // First, assume it's a full path name already.
+    if (Glib::file_test (a_file_path, Glib::FILE_TEST_IS_REGULAR)) {
+        a_absolute_path = a_file_path;
+        return true;
+    }
+    // If that didn't work, look for a file of that name in the search
+    // directories.
+    if (find_file_in_source_dirs (a_file_path, a_absolute_path)) {
+        return true;
+    }
+    return false;
+}
+
+bool
+DBGPerspective::find_absolute_path_or_ask_user (const UString& a_file_path,
+                                                UString& a_absolute_path)
+{
+    if (!find_absolute_path (a_file_path, a_absolute_path)) {
+        if (ask_user_to_select_file (a_file_path, a_absolute_path)) {
+            UString parent_dir = Glib::filename_to_utf8
+                                    (Glib::path_get_dirname (a_absolute_path));
+            m_priv->search_paths.push_back (parent_dir);
+        } else {
+            return false;
+        }
+    }
+    return true;
+}
+
 void
 DBGPerspective::append_source_editor (SourceEditor &a_sv,
                                       const UString &a_path)
@@ -4838,6 +4960,9 @@ DBGPerspective::get_file_mime_type (const UString &a_path,
     NEMIVER_CATCH_AND_RETURN (false)
 }
 
+// Make sure the source buffer a_buf is properly setup to have the mime
+// type a_mime_type. If a_buf is null, a new one is created.
+// Returns true upon successful completion, false otherwise.
 bool
 DBGPerspective::setup_buffer_mime_and_lang (Glib::RefPtr<SourceBuffer> &a_buf,
                                             const std::string &a_mime_type)
@@ -4996,7 +5121,7 @@ DBGPerspective::create_source_editor (Glib::RefPtr<SourceBuffer> &a_source_buf,
                                                        a_source_buf,
                                                        true));
         if (!a_current_address.empty ()) {
-            source_editor->composite_buf_loc_to_line (a_current_address.raw (),
+            source_editor->assembly_buf_loc_to_line (a_current_address.raw (),
                                                       current_line);
         }
     } else {
@@ -5087,7 +5212,8 @@ DBGPerspective::open_file (const UString &a_path,
                            int a_current_line)
 {
     RETURN_VAL_IF_FAIL (m_priv, false);
-    RETURN_VAL_IF_FAIL (!a_path.empty (), false);
+    if (a_path.empty ())
+        return false;
 
     if (get_source_editor_from_path (a_path)) {return true;}
 
@@ -5260,6 +5386,11 @@ DBGPerspective::load_disassembly (const IDebugger::DisassembleInfo &/*a_info*/,
     NEMIVER_CATCH_AND_RETURN (false)
 }
 
+// If new disassembly dedicated tab was already present in the perspective,
+// create  a new one, otherwise, reuse the one that was already present.
+// Then load the assembly insns a_asm  described by a_info into the
+// source buffer of the disassembly tab.
+// Return true upon successful completion, false otherwise.
 bool
 DBGPerspective::open_disassembly (const IDebugger::DisassembleInfo &a_info,
                                   const std::list<IDebugger::AsmInstr> &a_asm)
@@ -5269,25 +5400,108 @@ DBGPerspective::open_disassembly (const IDebugger::DisassembleInfo &a_info,
     NEMIVER_TRY
 
     Glib::RefPtr<SourceBuffer> source_buffer;
+
+    SourceEditor *source_editor =
+        get_source_editor_from_path (get_disassembly_title ());
+
+    if (source_editor) {
+        source_buffer = source_editor->source_view ().get_source_buffer ();
+        source_buffer->erase (source_buffer->begin (), source_buffer->end ());
+    }
     if (!load_disassembly (a_info, a_asm, source_buffer)) {
         return false;
     }
-
-    SourceEditor *source_editor =
-        create_source_editor (source_buffer,
-                              /*a_disassembly_view=*/true,
-                              get_disassembly_title (),
-                              -1,
-                              /*a_current_address=*/"");
-    THROW_IF_FAIL (source_editor);
-    source_editor->show_all ();
-    append_source_editor (*source_editor, get_disassembly_title ());
+    if (!source_editor) {
+        source_editor =
+            create_source_editor (source_buffer,
+                                  /*a_disassembly_view=*/true,
+                                  get_disassembly_title (),
+                                  -1,
+                                  /*a_current_address=*/"");
+        THROW_IF_FAIL (source_editor);
+        source_editor->show_all ();
+        append_source_editor (*source_editor, get_disassembly_title ());
+    }
 
     NEMIVER_CATCH_AND_RETURN (false);
 
     return true;
 }
 
+// Get the source editor of the source file being currently debugged,
+// switch it into the disassembly mode and load the asm insns
+// represented by a_info and a_asm into its source buffer.
+// \param a_info descriptor of the assembly instructions
+// \param a_asm a list of asm instructions.
+void
+DBGPerspective::switch_to_disassembly
+                    (const IDebugger::DisassembleInfo &a_info,
+                     const std::list<IDebugger::AsmInstr> &a_asm)
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+    SourceEditor *source_editor = get_current_source_editor ();
+    if (source_editor == 0)
+        return;
+
+    Glib::RefPtr<SourceBuffer> asm_buf;
+    if ((asm_buf = source_editor->get_assembly_source_buffer ()) == 0) {
+        setup_buffer_mime_and_lang (asm_buf, "test/x-asm");
+        source_editor->register_assembly_source_buffer (asm_buf);
+        asm_buf = source_editor->get_assembly_source_buffer ();
+        RETURN_IF_FAIL (asm_buf);
+    }
+    if (!load_disassembly (a_info, a_asm, asm_buf)) {
+        LOG_ERROR ("failed to load asm");
+        return;
+    }
+    if (!source_editor->switch_to_assembly_source_buffer ()) {
+        LOG_ERROR ("Could not switch the current view to asm");
+    }
+}
+
+// Get the source editor of the source file being currently debugged,
+// switch it into the source code mode. If necessary, (re) load the
+// source code.
+void
+DBGPerspective::switch_to_source_code ()
+{
+    SourceEditor *source_editor = get_current_source_editor ();
+    if (source_editor == 0)
+        return;
+    Glib::RefPtr<SourceBuffer> source_buf;
+    UString source_path;
+    if ((source_buf = source_editor->get_non_assembly_source_buffer ()) == 0) {
+        // Woops!
+        // We don't have any source code buffer. Let's try hard to get
+        // the source code corresponding to the current frame. For that,
+        // we'll hope to have proper debug info for the binary being
+        // debugged, and the source code available on disk.
+        if (m_priv->current_frame.address ().empty ()) {
+            LOG_DD ("No current instruction pointer");
+            return;
+        }
+        if (m_priv->current_frame.file_name ().empty ()) {
+            LOG_DD ("No file name information for current frame");
+            return;
+        }
+        UString absolute_path, mime_type;
+        if (!find_absolute_path_or_ask_user (m_priv->current_frame.file_name (),
+                                             absolute_path)) {
+            LOG_DD ("Could not find file: "
+                    << m_priv->current_frame.file_name ());
+            return;
+        }
+        get_file_mime_type (absolute_path, mime_type);
+        setup_buffer_mime_and_lang (source_buf, mime_type);
+        load_file (absolute_path, source_buf);
+        source_editor->register_non_assembly_source_buffer (source_buf);
+    }
+    source_editor->switch_to_non_assembly_source_buffer ();
+    source_editor->get_path (source_path);
+    apply_decorations_to_text (source_path);
+}
+
 Gtk::Widget*
 DBGPerspective::load_menu (const UString &a_filename,
                            const UString &a_widget_name)
@@ -6136,10 +6350,42 @@ DBGPerspective::append_visual_breakpoint (const UString &a_file_name,
                                      actual_file_path, enabled);
 }
 
+// Popup a dialog asking the user to select the file a_file_name.
+// \param a_file_name the name of the file we want the user to select.
+// \param a_selected_file_path the path to the file the user actually
+// selected.
+// \return true if the user really selected the file we wanted, false
+// otherwise.
+bool
+DBGPerspective::ask_user_to_select_file (const UString &a_file_name,
+                                         UString &a_selected_file_path)
+{
+    LocateFileDialog dialog (plugin_path (), a_file_name);
+    // start looking in the working directory
+    dialog.file_location (m_priv->prog_cwd);
+    int result = dialog.run ();
+    if (result == Gtk::RESPONSE_OK) {
+        UString file_path = dialog.file_location ();
+        if (!Glib::file_test (file_path, Glib::FILE_TEST_IS_REGULAR)
+            || (Glib::path_get_basename (a_file_name)
+                != Glib::path_get_basename (file_path)))
+            return false;
+        UString parent_dir =
+            Glib::filename_to_utf8 (Glib::path_get_dirname
+                                                (dialog.file_location ()));
+        if (!Glib::file_test (parent_dir, Glib::FILE_TEST_IS_DIR))
+            return false;
+
+        a_selected_file_path = file_path;
+        return true;
+    }
+    return false;
+}
+
 bool
 DBGPerspective::append_visual_breakpoint (const UString &a_file_name,
                                           int a_linenum,
-                                          UString &a_actual_file_name,
+                                          UString &a_actual_file_path,
                                           bool enabled)
 {
     if (a_file_name.empty()) {
@@ -6154,105 +6400,32 @@ DBGPerspective::append_visual_breakpoint (const UString &a_file_name,
 
     if (a_linenum < 0) {a_linenum = 0;}
 
-    UString actual_file_name;
+    UString actual_file_path;
     SourceEditor *source_editor =
                         get_source_editor_from_path (a_file_name,
-                                                     actual_file_name);
-    //first assume that it's a full pathname and just try to open it
-    if (!source_editor) {
-        if (Glib::file_test (a_file_name, Glib::FILE_TEST_IS_REGULAR)) {
-            if (!open_file (a_file_name)) {
-                UString msg;
-                msg.printf (_("Failed to open file %s. "
-                              "Would you like to open another file which "
-                              "would have the same content ?"),
-                            a_file_name.c_str ());
-                if (ui_utils::ask_yes_no_question (msg)
-                    == Gtk::RESPONSE_YES) {
-                    LocateFileDialog dialog (plugin_path (), a_file_name);
-                    dialog.file_location (m_priv->prog_cwd);
-                    int result = dialog.run ();
-                    if (result == Gtk::RESPONSE_OK) {
-                        UString file_path = dialog.file_location ();
-                        THROW_IF_FAIL (Glib::file_test (file_path,
-                                            Glib::FILE_TEST_IS_REGULAR));
-                        std::string raw_dir = Glib::path_get_dirname
-                            (dialog.file_location ());
-                        UString parent_dir = Glib::filename_to_utf8 (raw_dir);
-                        THROW_IF_FAIL (Glib::file_test (raw_dir,
-                                                        Glib::FILE_TEST_IS_DIR));
-                        m_priv->search_paths.push_back (parent_dir);
-                        if (!open_file (file_path)) {
-                            return false;
-                        }
-                        source_editor =
-                            get_source_editor_from_path (file_path,
-                                                         actual_file_name);
-                    } else {
-                        return false;
-                    }
-                } else {
-                    return false;
-                }
+                                                     actual_file_path);
+    if (source_editor == 0) {
+        if (!find_absolute_path (a_file_name, actual_file_path)) {
+            if (ask_user_to_select_file (a_file_name, actual_file_path)) {
+                UString parent_dir =
+                    Glib::filename_to_utf8
+                        (Glib::path_get_dirname (actual_file_path));
+                m_priv->search_paths.push_back (parent_dir);
             }
-            source_editor = get_source_editor_from_path (a_file_name,
-                                                         actual_file_name);
         }
-    }
-    //if that didn't work, look for an opened source editor
-    //that matches the base name
-    if (!source_editor) {
+        open_file (actual_file_path);
         source_editor = get_source_editor_from_path (a_file_name,
-                                                     actual_file_name,
-                                                     true);
+                                                      actual_file_path);
     }
-    //if that still didn't work, look for a file of that name in the search
-    //directories and then as a last resort ask the user to locate it
-    //manually
-    if (!source_editor) {
-        UString file_path;
-        if (!find_file_in_source_dirs (a_file_name, file_path)) {
-            LOG_DD ("didn't find file either in opened files "
-                    " or in source dirs:");
-            //Pop up a dialog asking user to select the specified file
-            LocateFileDialog dialog (plugin_path (), a_file_name);
-            //start looking in the working directory
-            dialog.file_location (m_priv->prog_cwd);
-            int result = dialog.run ();
-            if (result == Gtk::RESPONSE_OK) {
-                file_path = dialog.file_location ();
-                THROW_IF_FAIL (Glib::file_test (file_path,
-                                                Glib::FILE_TEST_IS_REGULAR));
-                THROW_IF_FAIL (Glib::path_get_basename(a_file_name) ==
-                        Glib::path_get_basename(file_path));
-                UString parent_dir = Glib::filename_to_utf8
-                    (Glib::path_get_dirname (dialog.file_location ()));
-                THROW_IF_FAIL (Glib::file_test
-                                    (parent_dir, Glib::FILE_TEST_IS_DIR));
-
-                //Also add the parent directory to the list
-                //of paths to search for this session so
-                //you don't have to keep selecting files if
-                //they're all in the same directory.
-                //We can assume that the parent
-                //directory is not already in the
-                //list of source dirs
-                //(or else it would have been found and the
-                //user wouldn't have had to locate it manually)
-                //so just stack it
-                //on the end of the list
-                m_priv->search_paths.push_back (parent_dir);
-            }
-        }
-
-        if (!file_path.empty ()) {
-            open_file (file_path);
-            source_editor = get_source_editor_from_path (file_path,
-                                                         actual_file_name);
-        }
+    // if that didn't work, look for an opened source editor
+    // that matches the base name
+    if (source_editor == 0) {
+        source_editor = get_source_editor_from_path (a_file_name,
+                                                     actual_file_path,
+                                                     /*basename_only=*/true);
     }
 
-    //finally, if none of these things worked, display an error
+    // finally, if none of these things worked, display an error
     if (!source_editor) {
         LOG_ERROR ("Could not find source editor for file: '"
                 << a_file_name
@@ -6263,7 +6436,7 @@ DBGPerspective::append_visual_breakpoint (const UString &a_file_name,
         source_editor->set_visual_breakpoint_at_line (a_linenum, enabled);
     }
 
-    a_actual_file_name = actual_file_name;
+    a_actual_file_path = actual_file_path;
     return true;
 }
 
@@ -6330,6 +6503,16 @@ DBGPerspective::choose_function_overload
         debugger ()->choose_function_overloads (nums);
 }
 
+void
+DBGPerspective::remove_visual_decorations_from_text
+                                            (const UString &a_file_path)
+{
+    SourceEditor *editor = get_source_editor_from_path (a_file_path);
+    if (editor == 0)
+        return;
+    editor->clear_decorations ();
+}
+
 bool
 DBGPerspective::apply_decorations_to_text (const UString &a_file_path)
 {
@@ -6597,6 +6780,42 @@ DBGPerspective::refresh_locals ()
 }
 
 void
+DBGPerspective::disassemble (bool a_show_asm_in_new_tab)
+{
+    THROW_IF_FAIL (m_priv);
+
+    // If we don't have the current instruction pointer (IP), there is
+    // nothing we can do.
+    if (!debugger ()->is_attached_to_target ()
+        || m_priv->current_frame.address ().empty ()) {
+        LOG_DD ("No current instruction pointer");
+        return;
+    }
+
+    sigc::slot<void,
+               const IDebugger::DisassembleInfo,
+               const std::list<IDebugger::AsmInstr>& > s;
+    if (a_show_asm_in_new_tab)
+        s = sigc::bind (sigc::mem_fun (this,
+                           &DBGPerspective::on_debugger_disassembled_signal),
+                        true);
+
+    else
+        s = sigc::bind
+                (sigc::mem_fun
+                     (this,
+                      &DBGPerspective::on_debugger_disassembled_signal),
+                 false);
+
+    debugger ()->disassemble
+                (0 /* Start @ to disassemble */,
+                 true /* Start @ is relative to current IP */,
+                 NUM_INSTR_TO_DISASSEMBLE * sizeof (void *),
+                 true /* End @ is relative to current IP */,
+                 s);
+}
+
+void
 DBGPerspective::toggle_breakpoint_enabled ()
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
diff --git a/src/uicommon/nmv-source-editor.cc b/src/uicommon/nmv-source-editor.cc
index 624cde8..624129c 100644
--- a/src/uicommon/nmv-source-editor.cc
+++ b/src/uicommon/nmv-source-editor.cc
@@ -173,7 +173,7 @@ struct SourceEditor::Priv {
     Gtk::Label *line_col_label;
     Gtk::HBox *status_box;
 
-    struct NonCompositeBufContext {
+    struct NonAssemblyBufContext {
         Glib::RefPtr<SourceBuffer> buffer;
         int current_column;
         int current_line;
@@ -181,7 +181,7 @@ struct SourceEditor::Priv {
         sigc::signal<void, int, bool> marker_region_got_clicked_signal;
         UString path;
 
-        NonCompositeBufContext (Glib::RefPtr<SourceBuffer> a_buf,
+        NonAssemblyBufContext (Glib::RefPtr<SourceBuffer> a_buf,
                                 int a_cur_col, int a_cur_line) :
             buffer (a_buf),
             current_column (a_cur_col),
@@ -189,72 +189,72 @@ struct SourceEditor::Priv {
         {
         }
 
-        NonCompositeBufContext (int a_cur_col, int a_cur_line) :
+        NonAssemblyBufContext (int a_cur_col, int a_cur_line) :
             current_column (a_cur_col),
             current_line (a_cur_line)
         {
         }
 
-        NonCompositeBufContext () :
+        NonAssemblyBufContext () :
             current_column (-1),
             current_line (-1)
         {
         }
-    } non_comp_ctxt;
+    } non_asm_ctxt;
 
-    struct CompositeBufContext {
+    struct AssemblyBufContext {
         Glib::RefPtr<SourceBuffer> buffer;
         Line2AddrFunc line_to_locus_func;
         Addr2LineFunc locus_to_line_func;
 
-        CompositeBufContext ()
+        AssemblyBufContext ()
         {
         }
 
-        CompositeBufContext
+        AssemblyBufContext
                     (Glib::RefPtr<SourceBuffer> a_buf) :
             buffer (a_buf)
         {
         }
-    } comp_ctxt;
+    } asm_ctxt;
 
     sigc::signal<void, const Gtk::TextBuffer::iterator&>
                                                     insertion_changed_signal;
 
 
-    void register_composite_source_buffer
+    void register_assembly_source_buffer
                     (Glib::RefPtr<SourceBuffer> &a_buf)
     {
-        comp_ctxt.buffer = a_buf;
+        asm_ctxt.buffer = a_buf;
     }
 
-    void register_non_composite_source_buffer
+    void register_non_assembly_source_buffer
                                     (Glib::RefPtr<SourceBuffer> &a_buf)
     {
-        non_comp_ctxt.buffer = a_buf;
+        non_asm_ctxt.buffer = a_buf;
     }
 
-    bool switch_to_composite_source_buffer ()
+    bool switch_to_assembly_source_buffer ()
     {
         RETURN_VAL_IF_FAIL (source_view, false);
 
-        if (comp_ctxt.buffer
+        if (asm_ctxt.buffer
             && (source_view->get_source_buffer ()
-                != comp_ctxt.buffer)) {
-            source_view->set_source_buffer (comp_ctxt.buffer);
+                != asm_ctxt.buffer)) {
+            source_view->set_source_buffer (asm_ctxt.buffer);
             return true;
         }
         return false;
     }
 
-    bool switch_to_non_composite_source_buffer ()
+    bool switch_to_non_assembly_source_buffer ()
     {
         RETURN_VAL_IF_FAIL (source_view, false);
 
-        if (comp_ctxt.buffer
+        if (asm_ctxt.buffer
             && (source_view->get_source_buffer ()
-                != non_comp_ctxt.buffer)) {
-            source_view->set_source_buffer (non_comp_ctxt.buffer);
+                != non_asm_ctxt.buffer)) {
+            source_view->set_source_buffer (non_asm_ctxt.buffer);
             return true;
         }
         return false;
@@ -265,7 +265,7 @@ struct SourceEditor::Priv {
     //**************
     void on_marker_region_got_clicked (int a_line, bool a_dialog_requested)
     {
-        non_comp_ctxt.marker_region_got_clicked_signal.emit
+        non_asm_ctxt.marker_region_got_clicked_signal.emit
                                                 (a_line, a_dialog_requested);
     }
 
@@ -288,8 +288,8 @@ struct SourceEditor::Priv {
     void on_signal_insertion_moved (gint a_line, gint a_col)
     {
         if (a_line || a_col) {}
-        non_comp_ctxt.current_line = a_line;
-        non_comp_ctxt.current_column = a_col;
+        non_asm_ctxt.current_line = a_line;
+        non_asm_ctxt.current_column = a_col;
         update_line_col_label ();
     }
 
@@ -321,7 +321,7 @@ struct SourceEditor::Priv {
             (sigc::mem_fun (*this, &SourceEditor::Priv::on_mark_set_signal));
         source_view->get_buffer ()->signal_insert ().connect
             (sigc::mem_fun (*this, &SourceEditor::Priv::on_signal_insert));
-        non_comp_ctxt.signal_insertion_moved.connect
+        non_asm_ctxt.signal_insertion_moved.connect
             (sigc::mem_fun (*this,
                             &SourceEditor::Priv::on_signal_insertion_moved));
         source_view->get_buffer ()->signal_mark_set ().connect
@@ -330,11 +330,11 @@ struct SourceEditor::Priv {
 
     void update_line_col_info_from_iter (const Gtk::TextBuffer::iterator &a_iter)
     {
-        non_comp_ctxt.current_line = a_iter.get_line () + 1;
-        non_comp_ctxt.current_column = get_column_from_iter (a_iter);
-        non_comp_ctxt.signal_insertion_moved.emit
-                                    (non_comp_ctxt.current_line,
-                                     non_comp_ctxt.current_column);
+        non_asm_ctxt.current_line = a_iter.get_line () + 1;
+        non_asm_ctxt.current_column = get_column_from_iter (a_iter);
+        non_asm_ctxt.signal_insertion_moved.emit
+                                    (non_asm_ctxt.current_line,
+                                     non_asm_ctxt.current_column);
     }
 
     void update_line_col_label ()
@@ -345,8 +345,8 @@ struct SourceEditor::Priv {
         }
         UString message;
         message.printf (_("Line: %i, Column: %i"),
-                        non_comp_ctxt.current_line,
-                        non_comp_ctxt.current_column);
+                        non_asm_ctxt.current_line,
+                        non_asm_ctxt.current_column);
         line_col_label->set_text (message);
     }
 
@@ -413,7 +413,7 @@ struct SourceEditor::Priv {
         source_view (Gtk::manage (new SourceView)),
         line_col_label (Gtk::manage (new Gtk::Label)),
         status_box (Gtk::manage (new Gtk::HBox)),
-        non_comp_ctxt (-1, -1)
+        non_asm_ctxt (-1, -1)
 
     {
         init ();
@@ -421,17 +421,17 @@ struct SourceEditor::Priv {
 
     explicit Priv (const UString &a_root_dir,
                    Glib::RefPtr<SourceBuffer> &a_buf,
-                   bool a_composite) :
+                   bool a_assembly) :
         root_dir (a_root_dir),
         source_view (Gtk::manage (new SourceView (a_buf))),
         line_col_label (Gtk::manage (new Gtk::Label)),
         status_box (Gtk::manage (new Gtk::HBox)),
-        non_comp_ctxt (a_buf, -1, -1)
+        non_asm_ctxt (a_buf, -1, -1)
     {
-        if (a_composite) {
-            comp_ctxt.buffer = a_buf;
+        if (a_assembly) {
+            asm_ctxt.buffer = a_buf;
         } else {
-            non_comp_ctxt.buffer = a_buf;
+            non_asm_ctxt.buffer = a_buf;
         }
         init ();
     }
@@ -441,7 +441,7 @@ struct SourceEditor::Priv {
         root_dir (a_root_dir),
         source_view (Gtk::manage (new SourceView (a_buf))),
         status_box (Gtk::manage (new Gtk::HBox)),
-        comp_ctxt (a_buf)
+        asm_ctxt (a_buf)
     {
         init ();
     }
@@ -485,9 +485,9 @@ SourceEditor::SourceEditor ()
 
 SourceEditor::SourceEditor (const UString &a_root_dir,
                             Glib::RefPtr<SourceBuffer> &a_buf,
-                            bool a_composite)
+                            bool a_assembly)
 {
-    m_priv.reset (new Priv (a_root_dir, a_buf, a_composite));
+    m_priv.reset (new Priv (a_root_dir, a_buf, a_assembly));
     init ();
 }
 
@@ -506,26 +506,26 @@ SourceEditor::source_view () const
 gint
 SourceEditor::current_line () const
 {
-    return m_priv->non_comp_ctxt.current_line;
+    return m_priv->non_asm_ctxt.current_line;
 }
 
 void
 SourceEditor::current_line (gint &a_line)
 {
-    m_priv->non_comp_ctxt.current_line = a_line;
+    m_priv->non_asm_ctxt.current_line = a_line;
 }
 
 gint
 SourceEditor::current_column () const
 {
-    return m_priv->non_comp_ctxt.current_column;
+    return m_priv->non_asm_ctxt.current_column;
 }
 
 void
 SourceEditor::current_column (gint &a_col)
 {
     LOG_DD ("current colnum " << (int) a_col);
-    m_priv->non_comp_ctxt.current_column = a_col;
+    m_priv->non_asm_ctxt.current_column = a_col;
 }
 
 void
@@ -665,6 +665,30 @@ SourceEditor::remove_visual_breakpoint_from_line (int a_line)
     m_priv->markers.erase (iter);
 }
 
+void
+SourceEditor::clear_decorations ()
+{
+#ifdef WITH_SOURCEVIEWMM2
+    std::map<int, Glib::RefPtr<gtksourceview::SourceMark> >::iterator it;
+#else
+    std::map<int, Glib::RefPtr<gtksourceview::SourceMarker> >::iterator it;
+#endif  // WITH_SOURCEVIEWMM2
+
+    // Clear breakpoint markers
+    for (it = m_priv->markers.begin (); it != m_priv->markers.end (); ++it) {
+        if (!it->second->get_deleted ()) {
+#ifdef WITH_SOURCEVIEWMM2
+            source_view ().get_source_buffer ()->delete_mark (it->second);
+#else
+            source_view ().get_source_buffer ()->delete_marker (it->second);
+#endif  // WITH_SOURCEVIEWMM2
+            m_priv->markers.erase (it);
+        }
+    }
+
+    unset_where_marker ();
+}
+
 bool
 SourceEditor::is_visual_breakpoint_set_at_line (int a_line) const
 {
@@ -732,20 +756,20 @@ SourceEditor::scroll_to_iter (Gtk::TextIter &a_iter)
 void
 SourceEditor::set_path (const UString &a_path)
 {
-    m_priv->non_comp_ctxt.path = a_path;
+    m_priv->non_asm_ctxt.path = a_path;
 }
 
 void
 SourceEditor::get_path (UString &a_path) const
 {
-    a_path = m_priv->non_comp_ctxt.path;
+    a_path = m_priv->non_asm_ctxt.path;
 }
 
 void
 SourceEditor::get_file_name (UString &a_file_name)
 {
     string path;
-    path = Glib::locale_from_utf8 (m_priv->non_comp_ctxt.path);
+    path = Glib::locale_from_utf8 (m_priv->non_asm_ctxt.path);
     path = Glib::path_get_basename (path);
     a_file_name = Glib::locale_to_utf8 (path);
 }
@@ -901,96 +925,96 @@ SourceEditor::do_search (const UString &a_str,
     return false;
 }
 
-/// Registers a composite source buffer
-/// \param a_buf the composite source buffer
+/// Registers a assembly source buffer
+/// \param a_buf the assembly source buffer
 /// \param a_line_to_locus_func a unary function that converts a line
 ///        number into a meaningful location for this source buffer.
 /// \param a_locus_to_line_func a unary function that converst a
 ///        meaningful location into a line buffer.
 void
-SourceEditor::register_composite_source_buffer
+SourceEditor::register_assembly_source_buffer
                     (Glib::RefPtr<SourceBuffer> &a_buf)
 {
-    m_priv->register_composite_source_buffer (a_buf);
+    m_priv->register_assembly_source_buffer (a_buf);
 }
 
-/// Registers a normal (non-composite) source buffer.
+/// Registers a normal (non-assembly) source buffer.
 /// \param a_buf the source buffer to register.
 void
-SourceEditor::register_non_composite_source_buffer
+SourceEditor::register_non_assembly_source_buffer
                                     (Glib::RefPtr<SourceBuffer> &a_buf)
 {
-    m_priv->register_non_composite_source_buffer (a_buf);
+    m_priv->register_non_assembly_source_buffer (a_buf);
 }
 
-/// Get the composite source buffer that was registered, or a NULL
+/// Get the assembly source buffer that was registered, or a NULL
 /// pointer if no one was registered before.
 /// \return a smart pointer to the source buffer.
 Glib::RefPtr<SourceBuffer>
-SourceEditor::get_composite_source_buffer () const
+SourceEditor::get_assembly_source_buffer () const
 {
-    return m_priv->comp_ctxt.buffer;
+    return m_priv->asm_ctxt.buffer;
 }
 
-/// Get the non-composite source buffer that was registered, or a NULL
+/// Get the non-assembly source buffer that was registered, or a NULL
 /// pointer if no one was registered before.
 /// \return a smart pointer to the source buffer.
 Glib::RefPtr<SourceBuffer>
-SourceEditor::get_non_composite_source_buffer () const
+SourceEditor::get_non_assembly_source_buffer () const
 {
-    return m_priv->non_comp_ctxt.buffer;
+    return m_priv->non_asm_ctxt.buffer;
 }
 
-/// Switch the editor to the composite source buffer that was
-/// registered. This function has no effect if no composite buffer was
+/// Switch the editor to the assembly source buffer that was
+/// registered. This function has no effect if no assembly buffer was
 /// registered.
 /// \return true if the switch was done, false otherwise.
 bool
-SourceEditor::switch_to_composite_source_buffer ()
+SourceEditor::switch_to_assembly_source_buffer ()
 {
-    return m_priv->switch_to_composite_source_buffer ();
+    return m_priv->switch_to_assembly_source_buffer ();
 }
 
-/// Switch the editor to the non-composite source buffer that was
-/// registered. This function has no effect if no non-composite source
+/// Switch the editor to the non-assembly source buffer that was
+/// registered. This function has no effect if no non-assembly source
 /// buffer was registered.
 /// \return true if the switch was done, false otherwise.
 bool
-SourceEditor::switch_to_non_composite_source_buffer ()
+SourceEditor::switch_to_non_assembly_source_buffer ()
 {
     RETURN_VAL_IF_FAIL (m_priv && m_priv->source_view, false);
 
-    if (m_priv->comp_ctxt.buffer
+    if (m_priv->asm_ctxt.buffer
         && (m_priv->source_view->get_source_buffer ()
-            != m_priv->non_comp_ctxt.buffer)) {
-        m_priv->source_view->set_source_buffer (m_priv->non_comp_ctxt.buffer);
+            != m_priv->non_asm_ctxt.buffer)) {
+        m_priv->source_view->set_source_buffer (m_priv->non_asm_ctxt.buffer);
         return true;
     }
     return false;
 }
 
 bool
-SourceEditor::composite_buf_loc_to_line (const Address &a_addr, int &a_line)
+SourceEditor::assembly_buf_loc_to_line (const Address &a_addr, int &a_line)
 {
-    Glib::RefPtr<SourceBuffer> buf = get_composite_source_buffer ();
+    Glib::RefPtr<SourceBuffer> buf = get_assembly_source_buffer ();
     RETURN_VAL_IF_FAIL (buf, false);
-    a_line = m_priv->comp_ctxt.locus_to_line_func (buf, a_addr);
+    a_line = m_priv->asm_ctxt.locus_to_line_func (buf, a_addr);
     return true;
 }
 
 bool
-SourceEditor::composite_buf_line_to_loc (int a_line, Address &a_address)
+SourceEditor::assembly_buf_line_to_loc (int a_line, Address &a_address)
 {
-    Glib::RefPtr<SourceBuffer> buf = get_composite_source_buffer ();
+    Glib::RefPtr<SourceBuffer> buf = get_assembly_source_buffer ();
     RETURN_VAL_IF_FAIL (buf, false);
-    a_address = m_priv->comp_ctxt.line_to_locus_func (buf, a_line);
+    a_address = m_priv->asm_ctxt.line_to_locus_func (buf, a_line);
     return true;
 }
 
 sigc::signal<void, int, bool>&
 SourceEditor::marker_region_got_clicked_signal () const
 {
-    return m_priv->non_comp_ctxt.marker_region_got_clicked_signal;
+    return m_priv->non_asm_ctxt.marker_region_got_clicked_signal;
 }
 
 sigc::signal<void, const Gtk::TextBuffer::iterator&>&
diff --git a/src/uicommon/nmv-source-editor.h b/src/uicommon/nmv-source-editor.h
index 4d660db..a9c59bf 100644
--- a/src/uicommon/nmv-source-editor.h
+++ b/src/uicommon/nmv-source-editor.h
@@ -75,6 +75,7 @@ public:
     void unset_where_marker ();
     void set_visual_breakpoint_at_line (int a_line, bool enabled=true);
     void remove_visual_breakpoint_from_line (int a_line);
+    void clear_decorations ();
     bool is_visual_breakpoint_set_at_line (int a_line) const;
     void scroll_to_line (int a_line);
     void scroll_to_iter (Gtk::TextIter &a_iter);
@@ -98,35 +99,35 @@ public:
     /// \name Composite Source buffer handling.
     /// @{
 
-    /// A composite buffer is a buffer which content doesn't come
+    /// A assembly buffer is a buffer which content doesn't come
     /// directly from a file. It as been composed in memory. We use
-    /// composite buffers to represent the assembly view of a text file
+    /// assemyb buffers to represent the assembly view of a text file
     /// being debugged.
-    /// Unlike non-composite buffers, meaningful locations inside the buffer
-    /// are not necessarily line numbers. They can be something else.
-    /// In the case of assembly view, a meaningful location is the address
+    /// Unlike non-assembly buffers, meaningful locations inside the buffer
+    /// are not necessarily line numbers.
+    /// In an assembly view, a meaningful location is the address
     /// of a machine instruction. So there somehow must be a kind of mapping
-    /// between the location used for the composite buffer and the actual
+    /// between the location used for the assembly buffer and the actual
     /// line number, because the underlying SourceBuffer implementation
     /// relies on line numbers anyhow.
 
-    void register_composite_source_buffer
+    void register_assembly_source_buffer
                         (Glib::RefPtr<SourceBuffer> &a_buf);
 
-    void register_non_composite_source_buffer
+    void register_non_assembly_source_buffer
                                     (Glib::RefPtr<SourceBuffer> &a_buf);
 
-    Glib::RefPtr<SourceBuffer> get_composite_source_buffer () const;
+    Glib::RefPtr<SourceBuffer> get_assembly_source_buffer () const;
 
-    Glib::RefPtr<SourceBuffer> get_non_composite_source_buffer () const;
+    Glib::RefPtr<SourceBuffer> get_non_assembly_source_buffer () const;
 
-    bool switch_to_composite_source_buffer ();
+    bool switch_to_assembly_source_buffer ();
 
-    bool switch_to_non_composite_source_buffer ();
+    bool switch_to_non_assembly_source_buffer ();
 
-    bool composite_buf_loc_to_line (const Address &, int &);
+    bool assembly_buf_loc_to_line (const Address &, int &);
 
-    bool composite_buf_line_to_loc (int, Address &);
+    bool assembly_buf_line_to_loc (int, Address &);
     /// @}
 
     /// \name signals



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]