[nemiver/gtk2-branch] Introduce Loc (code location) type



commit bb8b6872be5d32e895e7ed2497fd16a4af88c31f
Author: Dodji Seketeli <dodji seketeli org>
Date:   Thu Apr 21 22:02:08 2011 +0200

    Introduce Loc (code location) type
    
    	* src/common/Makefile.am: Add nmv-loc.h to build system.
    	* src/common/nmv-loc.h: New file.
    	* src/dbgengine/nmv-i-debugger.h (IDebugger::set_breakpoint):
    	New overload that takes an instance of Loc.
    	* src/dbgengine/nmv-debugger-utils.h (null_default_slot)
    	(null_disass_slot, null_breakpoints_slot): New declarations.
    	* src/dbgengine/nmv-debugger-utils.cc (null_default_slot)
    	(null_disass_slot, null_breakpoints_slot): New definitions.
    	* src/dbgengine/nmv-gdb-engine.cc (location_to_string): New
    	helpers to serialize instance of Loc.
    	(OnBreakpointHandler::handle): Call the argument callback slot
    	when the command was "set-breakpoint".
    	(GDBEngine::set_breakpoint): New overload definition that takes an
    	instance of Loc in argument, as well as callback slot.
    	(null_disass_slot): Remove this from here.
    	* src/dbgengine/nmv-gdb-engine.h (GDBEngine::set_breakpoint): New
    	overload declaration.

 src/common/Makefile.am              |    3 +-
 src/common/nmv-loc.h                |  158 +++++++++++++++++++++++++++++++++++
 src/dbgengine/nmv-debugger-utils.cc |   21 +++++
 src/dbgengine/nmv-debugger-utils.h  |   12 +++
 src/dbgengine/nmv-gdb-engine.cc     |  151 ++++++++++++++++++++++++++++++++--
 src/dbgengine/nmv-gdb-engine.h      |    8 ++-
 src/dbgengine/nmv-i-debugger.h      |   12 +++
 7 files changed, 357 insertions(+), 8 deletions(-)
---
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index eaa09d0..5b61d90 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -41,7 +41,8 @@ $(h)/nmv-sql-statement.h \
 $(h)/nmv-insert-statement.h \
 $(h)/nmv-delete-statement.h \
 $(h)/nmv-proc-utils.h \
-$(h)/nmv-proc-mgr.h
+$(h)/nmv-proc-mgr.h \
+$(h)/nmv-loc.h
 
 libnemivercommon_la_SOURCES= $(headers) \
 $(h)/nmv-ustring.cc \
diff --git a/src/common/nmv-loc.h b/src/common/nmv-loc.h
new file mode 100644
index 0000000..277331f
--- /dev/null
+++ b/src/common/nmv-loc.h
@@ -0,0 +1,158 @@
+//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_LOC_H__
+#define __NEMIVER_LOC_H__
+
+#include "nmv-ustring.h"
+#include "nmv-address.h"
+#include "nmv-api-macros.h"
+
+/// \file
+/// The declaration of source, function and addresses related location
+/// types.  For now, it's only the debugging engine backend that knows
+/// how to serialize a location into a location string.
+
+NEMIVER_BEGIN_NAMESPACE (nemiver)
+NEMIVER_BEGIN_NAMESPACE (common)
+
+///  The base type presenting a location.
+class NEMIVER_API Loc
+{
+
+ public:
+    /// The different possible kinds of locations.
+    enum Kind
+    {
+        UNDEFINED_LOC_KIND,
+        SOURCE_LOC_KIND,
+        FUNCTION_LOC_KIND,
+        ADDRESS_LOC_KIND
+    };
+
+ protected:
+    Kind m_kind;
+
+    Loc ()
+        : m_kind (UNDEFINED_LOC_KIND)
+    {
+    }
+    
+    
+    Loc (const Loc &a)
+      : m_kind (a.m_kind)
+    {
+    }
+
+ public:
+    Kind kind () const {return m_kind;}
+    virtual ~Loc () {};
+}; // end class Loc
+
+/// A source location.
+/// 
+/// It encapsulates a file name and a line number
+/// in that file.
+class NEMIVER_API SourceLoc : public Loc
+{
+    UString m_file_path;
+    int m_line_number;
+
+ public:
+    SourceLoc (const UString &a_file_path,
+               int a_line_number)
+        : m_file_path (a_file_path),
+        m_line_number (a_line_number)
+    {
+        m_kind = SOURCE_LOC_KIND;
+    }
+
+    SourceLoc (const SourceLoc &a)
+      : Loc (a)
+    {
+        m_file_path = a.m_file_path;
+        m_line_number = a.m_line_number;
+    }
+
+    const UString& file_path () const {return m_file_path;}
+    void file_path (const UString &a) {m_file_path = a;}
+    int line_number () const {return m_line_number;}
+    void line_number (int a) {m_line_number = a;}
+};// end class SourceLoc;
+
+/// A function location.
+///
+/// It encapsulates the location of a function.
+class NEMIVER_API FunctionLoc : public Loc
+{
+    UString m_function_name;
+
+ public:
+
+    FunctionLoc (const UString &a_function_name)
+        : m_function_name (a_function_name)
+    {
+        m_kind = FUNCTION_LOC_KIND;
+    }
+
+    FunctionLoc (const FunctionLoc &a)
+      : Loc (a),
+      m_function_name (a.m_function_name)
+    {
+    }
+
+    const UString& function_name () const {return m_function_name;}
+    void function_name (const UString &a) {m_function_name = a;}
+};
+
+/// An address location.
+///
+/// It encapslates an address.
+class NEMIVER_API AddressLoc : public Loc
+{
+    Address m_address;
+
+ public:
+
+    AddressLoc (const Address &a)      
+      : m_address (a)
+    {
+        m_kind = ADDRESS_LOC_KIND;
+    }
+
+    AddressLoc (const AddressLoc &a)
+      : Loc (a),
+      m_address (a.m_address)
+    {
+    }
+
+    const Address& address () const {return m_address;}
+    void address (const Address &a) {m_address = a;}
+};
+
+NEMIVER_END_NAMESPACE (common)
+NEMIVER_END_NAMESPACE (nemiver)
+
+#endif //__NEMIVER_LOC_H__
diff --git a/src/dbgengine/nmv-debugger-utils.cc b/src/dbgengine/nmv-debugger-utils.cc
index 4e78dd1..9c97815 100644
--- a/src/dbgengine/nmv-debugger-utils.cc
+++ b/src/dbgengine/nmv-debugger-utils.cc
@@ -29,6 +29,10 @@
 NEMIVER_BEGIN_NAMESPACE (nemiver)
 NEMIVER_BEGIN_NAMESPACE (debugger_utils)
 
+/// \name Definitions of no-op callback slots that can used by client
+/// code.
+/// 
+/// @{
 void
 null_const_variable_slot (const IDebugger::VariableSafePtr &)
 {
@@ -54,6 +58,23 @@ null_frame_args_slot (const map<int, IDebugger::VariableList> &)
 {
 }
 
+void
+null_default_slot ()
+{
+}
+
+void
+null_disass_slot (const common::DisassembleInfo &,
+                  const std::list<common::Asm> &)
+{
+}
+
+void
+null_breakpoints_slot (const map<int, IDebugger::Breakpoint>&)
+{
+}
+///@}
+
 /// Generate a string of of white spaces.
 /// \param a_nb_ws the number of white spaces to generate
 /// \param a_ws_str the output string the white spaces are
diff --git a/src/dbgengine/nmv-debugger-utils.h b/src/dbgengine/nmv-debugger-utils.h
index 75026d7..479d13c 100644
--- a/src/dbgengine/nmv-debugger-utils.h
+++ b/src/dbgengine/nmv-debugger-utils.h
@@ -32,6 +32,9 @@
 NEMIVER_BEGIN_NAMESPACE (nemiver)
 NEMIVER_BEGIN_NAMESPACE (debugger_utils)
 
+/// \name Declarations of no-op callback slots
+///
+/// @{
 void null_const_variable_slot (const IDebugger::VariableSafePtr &);
 
 void null_const_variable_list_slot (const IDebugger::VariableList &);
@@ -42,6 +45,15 @@ void null_frame_vector_slot (const vector<IDebugger::Frame> &);
 
 void null_frame_args_slot (const map<int, IDebugger::VariableList> &);
 
+void null_default_slot ();
+
+void null_disass_slot (const common::DisassembleInfo &,
+		       const std::list<common::Asm> &);
+
+void null_breakpoints_slot (const map<int, IDebugger::Breakpoint>&);
+
+/// @}
+
 void dump_variable_value (IDebugger::VariableSafePtr a_var,
                           int a_indent_num,
                           std::ostringstream &a_os,
diff --git a/src/dbgengine/nmv-gdb-engine.cc b/src/dbgengine/nmv-gdb-engine.cc
index 3f7b184..ea95e89 100644
--- a/src/dbgengine/nmv-gdb-engine.cc
+++ b/src/dbgengine/nmv-gdb-engine.cc
@@ -57,6 +57,8 @@ using nemiver::debugger_utils::null_const_variable_slot;
 using nemiver::debugger_utils::null_const_variable_list_slot;
 using nemiver::debugger_utils::null_frame_vector_slot;
 using nemiver::debugger_utils::null_frame_args_slot;
+using nemiver::debugger_utils::null_disass_slot;
+using nemiver::debugger_utils::null_breakpoints_slot;
 
 NEMIVER_BEGIN_NAMESPACE (nemiver)
 
@@ -79,6 +81,88 @@ quote_args (const vector<UString> &a_prog_args)
     return args;
 }
 
+//**************************************************************
+// <Helper functions to generate a serialized form of location>
+//**************************************************************
+
+/// Generate a location string from a an instance of source location
+/// type.
+///
+/// \param a_loc the source input location
+///
+/// \param a_str the resulting location string
+static void
+location_to_string (const SourceLoc &a_loc,
+                    UString &a_str)
+{
+    a_str =
+        a_loc.file_path ()
+        + ":" + UString::from_int (a_loc.line_number ());
+}
+
+/// Generate a location string from a an instance of address location
+/// type.
+///
+/// \param a_loc the input address location
+///
+/// \param a_str the resulting location string
+static void
+location_to_string (const AddressLoc &a_loc,
+                    UString &a_str)
+{
+    a_str = "*" + a_loc.address ().to_string ();
+}
+
+/// Generate a location string from a an instance of function location
+/// type.
+///
+/// \param a_loc the input function location
+///
+/// \param a_str the resulting location string
+static void
+location_to_string (const FunctionLoc &a_loc,
+                    UString &a_str)
+{
+    a_str = a_loc.function_name ();
+}
+
+/// Generate a location string from a generic instance of location
+/// type.
+///
+/// \param a_loc the input location
+///
+/// \param a_str the resulting location string
+static void
+location_to_string (const Loc &a_loc,
+                    UString &a_str)
+{
+    switch (a_loc.kind ()) {
+    case Loc::UNDEFINED_LOC_KIND:
+        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);
+    }
+        break;
+
+    case Loc::FUNCTION_LOC_KIND: {
+        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);
+    }
+        break;
+    }
+}
+
+//**************************************************************
+// </Helper functions to generate a serialized form of location>
+//**************************************************************
 
 //*************************
 //<GDBEngine::Priv struct>
@@ -1330,6 +1414,12 @@ struct OnBreakpointHandler: OutputHandler {
             }
         } else if (has_breaks) {
             LOG_DD ("firing IDebugger::breakpoint_set_signal()");
+            Command &c = a_in.command ();
+            if (c.name () == "set-breakpoint"
+                && c.has_slot ()) {
+                IDebugger::BreakpointsSlot slot = c.get_slot<IDebugger::BreakpointsSlot> ();
+                slot (m_engine->get_cached_breakpoints ());
+            }
             m_engine->breakpoints_set_signal ().emit
                 (m_engine->get_cached_breakpoints (),
                  a_in.command ().cookie ());
@@ -3778,6 +3868,61 @@ GDBEngine::continue_to_position (const UString &a_path,
                             a_cookie));
 }
 
+/// Set a breakpoint at a location in the inferior.
+///
+/// \param a_loc the location of the breakpoint.
+///
+/// \param a_condition the condition of the breakpoin.  If there is no
+/// condition, the argument should be "".
+///
+/// \param a_ignore_count the number of time the breakpoint should be
+/// hit before execution of the inferior is stopped.
+///
+/// \param a_slot a callback slot to be invoked once the breakpoint is
+/// set.
+///
+/// \param a_cookie a string to be passed to
+/// IDebugger::breakpoints_set_signals once that signal emitted as a
+/// result of the breakpoint being set.  Note both a_slot and
+/// IDebugger::breakpoint_set_signals are 'called' upon breakpoint
+/// actual setting.  Eventually, IDebugger::breakpoints_set_signals
+/// should be dropped, so this whole cookie business would disapear.
+/// We are still in a transitional period.
+void
+GDBEngine::set_breakpoint (const Loc &a_loc,
+                           const UString &a_condition,
+                           gint a_ignore_count,
+                           const BreakpointsSlot &a_slot,
+                           const UString &a_cookie)
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+    THROW_IF_FAIL (a_loc.kind () != Loc::UNDEFINED_LOC_KIND);
+
+    UString loc_str;
+
+    location_to_string (a_loc, loc_str);
+
+    UString break_cmd = "-break-insert -f ";
+    if (!a_condition.empty ()) {
+        LOG_DD ("setting breakpoint with condition: " << a_condition);
+        break_cmd += " -c \"" + a_condition + "\"";
+    } else {
+        LOG_DD ("setting breakpoint without condition");
+    }
+
+    bool count_point = (a_ignore_count < 0);
+    if (!count_point)
+        break_cmd += " -i " + UString::from_int (a_ignore_count);
+
+    break_cmd += " " + loc_str;
+    string cmd_name = count_point ? "set-countpoint" : "set-breakpoint";
+    
+    Command command (cmd_name, break_cmd, a_cookie);
+    command.set_slot (a_slot);
+    queue_command (command);
+}
+
 void
 GDBEngine::set_breakpoint (const UString &a_path,
                            gint a_line_num,
@@ -4861,12 +5006,6 @@ GDBEngine::set_memory (size_t a_addr,
 }
 
 void
-null_disass_slot (const common::DisassembleInfo &,
-                  const std::list<common::Asm> &)
-{
-}
-
-void
 GDBEngine::disassemble (size_t a_start_addr,
                         bool a_start_addr_relative_to_pc,
                         size_t a_end_addr,
diff --git a/src/dbgengine/nmv-gdb-engine.h b/src/dbgengine/nmv-gdb-engine.h
index 964a641..da48b39 100644
--- a/src/dbgengine/nmv-gdb-engine.h
+++ b/src/dbgengine/nmv-gdb-engine.h
@@ -328,11 +328,17 @@ public:
                                gint a_line_num,
                                const UString &a_cookie) ;
 
+    void set_breakpoint (const Loc &a_loc,
+			 const UString &a_condition,
+			 gint a_ignore_count,
+			 const BreakpointsSlot &a_slot,
+			 const UString &a_cookie);
+
     void set_breakpoint (const UString &a_path,
                          gint a_line_num,
                          const UString &a_condition,
                          gint a_ignore_count,
-                         const UString &a_cookie) ;
+                         const UString &a_cookie);
 
     void set_breakpoint (const UString &a_func_name,
                          const UString &a_condition,
diff --git a/src/dbgengine/nmv-i-debugger.h b/src/dbgengine/nmv-i-debugger.h
index 55823a8..eb75fbd 100644
--- a/src/dbgengine/nmv-i-debugger.h
+++ b/src/dbgengine/nmv-i-debugger.h
@@ -37,6 +37,7 @@
 #include "common/nmv-safe-ptr-utils.h"
 #include "common/nmv-address.h"
 #include "common/nmv-asm-instr.h"
+#include "common/nmv-loc.h"
 #include "nmv-i-conf-mgr.h"
 
 using nemiver::common::SafePtr;
@@ -52,6 +53,7 @@ using nemiver::common::AsmInstr;
 using nemiver::common::MixedAsmInstr;
 using nemiver::common::Asm;
 using nemiver::common::DisassembleInfo;
+using nemiver::common::Loc;
 using std::vector;
 using std::string;
 using std::map;
@@ -819,6 +821,10 @@ public:
         return false;
     }
 
+    typedef sigc::slot<void> DefaultSlot;
+    typedef sigc::slot<void, const map<int, IDebugger::Breakpoint>&> BreakpointsSlot;
+    typedef sigc::slot<void, Loc&> LocSlot;
+    
     virtual ~IDebugger () {}
 
     /// \name events you can connect to.
@@ -1115,6 +1121,12 @@ public:
                                        gint a_line_num,
                                        const UString &a_cookie="") = 0;
 
+    virtual void set_breakpoint (const common::Loc &a_loc,
+                                 const UString &a_condition,
+                                 gint a_ignore_count,
+                                 const BreakpointsSlot &a_slot,
+                                 const UString &a_cookie = "") = 0;
+
     virtual void set_breakpoint (const UString &a_path,
                                  gint a_line_num,
                                  const UString &a_condition= "",



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