[nemiver/varobjs-support] New IDebugger::query_variable_path_expr.



commit 7e374a20b3b5745f4bbc91634970edaff264f379
Author: Dodji Seketeli <dodji redhat com>
Date:   Sat May 23 23:47:34 2009 +0200

    New IDebugger::query_variable_path_expr.
    
    	* src/dbgengine/nmv-i-debugger.h
    	(IDebugger::Variable::path_expression): New accessor for the
    	path expression of a variable.
    	(IDebugger::query_variable_path_expr): Declare new abstract interface entry
    	point.
    	(GDBEngine::query_variable_path_expr): Declare new concrete
    	interface entry point.
    	* src/dbgengine/nmv-gdb-engine.cc:
    	(GDBEngine::query_variable_path_expr): New implementation of
    	IDebugger::query_variable_path_expr. Sends
    	-var-info-path-expression to GDB.
    	(OnCommandDoneHandler::do_handle): Notify client code whenever
    	we receive the reply of -var-info-path-expression.
    	* tests/test-var-path-expr.cc: New test.
    	* tests/Makefile.am: Add the new test to the build system.
---
 src/dbgengine/nmv-gdb-engine.cc |   49 ++++++++++++
 src/dbgengine/nmv-gdb-engine.h  |    7 ++
 src/dbgengine/nmv-i-debugger.h  |   42 ++++++++---
 tests/Makefile.am               |    7 ++-
 tests/test-var-path-expr.cc     |  158 +++++++++++++++++++++++++++++++++++++++
 5 files changed, 252 insertions(+), 11 deletions(-)

diff --git a/src/dbgengine/nmv-gdb-engine.cc b/src/dbgengine/nmv-gdb-engine.cc
index 1524066..273c07e 100644
--- a/src/dbgengine/nmv-gdb-engine.cc
+++ b/src/dbgengine/nmv-gdb-engine.cc
@@ -1282,6 +1282,21 @@ struct OnCommandDoneHandler : OutputHandler {
 
         m_engine->command_done_signal ().emit (a_in.command ().name (),
                                                a_in.command ().cookie ());
+
+        if (a_in.command ().name () == "query-variable-path-expr"
+            && a_in.command ().variable ()
+            && a_in.output ().result_record ().has_path_expression ()) {
+            a_in.command ().variable ()->path_expression
+                        (a_in.output ().result_record ().path_expression ());
+            // Call the slot associated to
+            // IDebugger::query_varaible_path_expr
+            if (a_in.command ().has_slot ()) {
+                typedef sigc::slot<void, const IDebugger::VariableSafePtr>
+                                                                    SlotType;
+                SlotType slot = a_in.command ().get_slot<SlotType> ();
+                slot (a_in.command ().variable ());
+            }
+        }
         //TODO: this is not necessarily true. Before setting the state
         //to ready here, one must now which command exactly was fired so
         //that gdb returned the "DONE" status for it.
@@ -4052,6 +4067,11 @@ null_const_variable_list_slot (const IDebugger::VariableList &)
 }
 
 void
+null_const_ustring_slot (const UString &)
+{
+}
+
+void
 GDBEngine::create_variable (const UString &a_name,
                             const UString &a_cookie)
 {
@@ -4235,6 +4255,35 @@ GDBEngine::list_changed_variables
     queue_command (command);
 }
 
+void
+GDBEngine::query_variable_path_expr (const VariableSafePtr a_var,
+                                     const UString &a_cookie)
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+    query_variable_path_expr (a_var, &null_const_variable_slot, a_cookie);
+}
+
+void
+GDBEngine::query_variable_path_expr (const VariableSafePtr a_var,
+                                     const ConstVariableSlot &a_slot,
+                                     const UString &a_cookie)
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+    THROW_IF_FAIL (a_var);
+    THROW_IF_FAIL (!a_var->internal_name ().empty ());
+
+    UString cmd_str = "-var-info-path-expression ";
+    cmd_str += a_var->internal_name ();
+
+    Command command ("query-variable-path-expr",
+                     cmd_str, a_cookie);
+    command.variable (a_var);
+    command.set_slot (a_slot);
+    queue_command (command);
+}
+
 //****************************
 //</GDBEngine methods>
 //****************************
diff --git a/src/dbgengine/nmv-gdb-engine.h b/src/dbgengine/nmv-gdb-engine.h
index e02d2b0..64c56d7 100644
--- a/src/dbgengine/nmv-gdb-engine.h
+++ b/src/dbgengine/nmv-gdb-engine.h
@@ -458,6 +458,13 @@ public:
                 (VariableSafePtr a_root,
                  const ConstVariableListSlot &a_slot,
                  const UString &a_cookie);
+
+    void query_variable_path_expr (const VariableSafePtr a_root,
+                                   const UString &a_cookie);
+
+    void query_variable_path_expr (const VariableSafePtr,
+                                   const ConstVariableSlot &a_slot,
+                                   const UString &a_cookie);
 };//end class GDBEngine
 
 NEMIVER_END_NAMESPACE (nemiver)
diff --git a/src/dbgengine/nmv-i-debugger.h b/src/dbgengine/nmv-i-debugger.h
index 1ae1ed5..dd1ebdf 100644
--- a/src/dbgengine/nmv-i-debugger.h
+++ b/src/dbgengine/nmv-i-debugger.h
@@ -318,6 +318,11 @@ public:
         //it points to is stored in m_dereferenced
         VariableSafePtr m_dereferenced;
         unsigned int m_num_expected_children;
+        // The expression with which this variable
+        // Can be referenced in the debugger.
+        // If empty, it can be set by calling
+        // IDebugger::query_variable_path_expr()
+        UString m_path_expression;
 
     public:
         Variable (const UString &a_internal_name,
@@ -689,6 +694,15 @@ public:
             }
             return result;
         }
+
+        const UString& path_expression () const
+        {
+            return m_path_expression;
+        }
+        void path_expression (const UString &a_expr)
+        {
+            m_path_expression = a_expr;
+        }
     };//end class Variable
 
     enum State {
@@ -1103,31 +1117,32 @@ public:
 
     typedef sigc::slot<void, const VariableSafePtr> ConstVariableSlot;
     typedef sigc::slot<void, const VariableList> ConstVariableListSlot;
+    typedef sigc::slot<void, const UString&> ConstUStringSlot;
 
     virtual void create_variable (const UString &a_name,
-                                  const UString &a_cookie="") = 0;
+                                  const UString &a_cookie = "") = 0;
 
     virtual void create_variable (const UString &a_name,
                                   const ConstVariableSlot &a_slot,
-                                  const UString &a_cookie="") = 0;
+                                  const UString &a_cookie = "") = 0;
 
     virtual void delete_variable (const VariableSafePtr a_var,
-                                  const UString &a_cookie="") = 0;
+                                  const UString &a_cookie = "") = 0;
 
     virtual void delete_variable (const VariableSafePtr a_var,
                                   const ConstVariableSlot&,
-                                  const UString &a_cookie="") = 0;
+                                  const UString &a_cookie = "") = 0;
 
     virtual void unfold_variable (VariableSafePtr a_var,
-                                  const UString &a_cookie) = 0;
+                                  const UString &a_cookie = "") = 0;
     virtual void unfold_variable
                 (VariableSafePtr a_var,
                  const ConstVariableSlot&,
-                 const UString &a_cookie="") = 0;
+                 const UString &a_cookie = "") = 0;
 
     virtual void assign_variable (const VariableSafePtr a_var,
                                   const UString &a_expression,
-                                  const UString &a_cookie) = 0;
+                                  const UString &a_cookie = "") = 0;
 
     virtual void assign_variable
                     (const VariableSafePtr a_var,
@@ -1136,18 +1151,25 @@ public:
                      const UString &a_cookie="") = 0;
 
     virtual void evaluate_variable_expr (const VariableSafePtr a_var,
-                                         const UString &a_cookie) = 0;
+                                         const UString &a_cookie = "") = 0;
     virtual void evaluate_variable_expr
             (const VariableSafePtr a_var,
              const ConstVariableSlot &a_slot,
-             const UString &a_cookie="")= 0;
+             const UString &a_cookie = "")= 0;
 
     virtual void list_changed_variables (VariableSafePtr a_root,
-                                         const UString &a_cookie) = 0;
+                                         const UString &a_cookie = "") = 0;
     virtual void list_changed_variables
             (VariableSafePtr a_root,
              const ConstVariableListSlot &a_slot,
              const UString &a_cookie="") = 0;
+
+    virtual void query_variable_path_expr (const VariableSafePtr a_var,
+                                           const UString &a_cookie = "") = 0;
+    virtual void query_variable_path_expr (const VariableSafePtr a_var,
+                                           const ConstVariableSlot &a_slot,
+                                           const UString &a_cookie = "") = 0;
+
 };//end IDebugger
 
 NEMIVER_END_NAMESPACE (nemiver)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 94be6a2..19058b8 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,5 +1,6 @@
 if VAROBJS
     WATCHPOINT_TEST=runtestwatchpoint
+    VAR_PATH_EXPR_TEST=runtestvarpathexpr
 else
     WATCHPOINT_TEST=
 endif
@@ -16,7 +17,7 @@ runtestvars runtestcpptrait runtestvarlist \
 runtestvarwalker runtestbreakpoint \
 $(WATCHPOINT_TEST) runtestderef \
 runtestlocalvarslist runtestcpplexer \
-runtestcppparser  \
+runtestcppparser $(VAR_PATH_EXPR_TEST) \
 runtestlibtoolwrapperdetection \
 runtestenv runtesttypes
 
@@ -58,6 +59,10 @@ if VAROBJS
 runtestwatchpoint_SOURCES=test-watchpoint.cc
 runtestwatchpoint_LDADD= NEMIVERCOMMON_LIBS@ \
 $(top_builddir)/src/common/libnemivercommon.la
+
+runtestvarpathexpr_SOURCES=test-var-path-expr.cc
+runtestvarpathexpr_LDADD= NEMIVERCOMMON_LIBS@ \
+$(top_builddir)/src/common/libnemivercommon.la
 endif
 
 #runtestoverloads_SOURCES=test-overloads.cc
diff --git a/tests/test-var-path-expr.cc b/tests/test-var-path-expr.cc
new file mode 100644
index 0000000..6f1de6d
--- /dev/null
+++ b/tests/test-var-path-expr.cc
@@ -0,0 +1,158 @@
+#include <iostream>
+#include <boost/test/minimal.hpp>
+#include <glibmm.h>
+#include "common/nmv-initializer.h"
+#include "common/nmv-safe-ptr-utils.h"
+#include "common/nmv-exception.h"
+#include "nmv-i-debugger.h"
+
+using namespace nemiver;
+using namespace nemiver::common ;
+
+#ifdef WITH_VAROBJS
+
+Glib::RefPtr<Glib::MainLoop> loop =
+    Glib::MainLoop::create (Glib::MainContext::get_default ()) ;
+
+static void
+on_engine_died_signal ()
+{
+    MESSAGE ("engine died") ;
+    loop->quit () ;
+}
+
+static void
+on_program_finished_signal ()
+{
+    MESSAGE ("program finished") ;
+    loop->quit () ;
+}
+
+static void
+on_breakpoints_set_signal (const std::map<int, IDebugger::BreakPoint> &a_breaks,
+                           const UString &a_cookie)
+{
+    if (a_cookie.empty ()) {}
+
+    MESSAGE ("breakpoints set:") ;
+    std::map<int, IDebugger::BreakPoint>::const_iterator it ;
+    for (it = a_breaks.begin () ; it != a_breaks.end () ; ++it) {
+        MESSAGE ("<break><num>" << it->first <<"</num><line>"
+                 << it->second.file_name () << ":" << it->second.line ()
+                 << "</line></break>");
+    }
+}
+
+static void
+on_variable_expr_path (const IDebugger::VariableSafePtr a_var)
+{
+    MESSAGE ("var expr path: " << a_var->path_expression ());
+    BOOST_REQUIRE (a_var->path_expression ()
+                   == "((((person).m_first_name)).npos)");
+    loop->quit ();
+}
+
+static void
+on_variable_unfolded (const IDebugger::VariableSafePtr a_var,
+                      IDebuggerSafePtr a_debugger)
+{
+    MESSAGE ("var unfolded: " << a_var->name ());
+
+    BOOST_REQUIRE (!a_var->members ().empty ());
+    if (a_var->members ().front ()->needs_unfolding ()) {
+        MESSAGE ("unfolding variable " << a_var->members ().front ()->name ());
+        a_debugger->unfold_variable (a_var->members ().front (),
+                                     sigc::bind (&on_variable_unfolded,
+                                                 a_debugger));
+    } else {
+        a_debugger->query_variable_path_expr (a_var->members ().front (),
+                                              &on_variable_expr_path);
+    }
+}
+
+static void
+on_variable_created (const IDebugger::VariableSafePtr a_var,
+                     IDebuggerSafePtr a_debugger)
+{
+    MESSAGE ("variable created: " << a_var->name ());
+
+    if (a_var->needs_unfolding ()) {
+        MESSAGE ("unfolding variable " << a_var->name ());
+        a_debugger->unfold_variable (a_var,
+                                     sigc::bind (&on_variable_unfolded,
+                                                 a_debugger));
+    }
+}
+
+static void
+on_stopped_signal (IDebugger::StopReason a_reason,
+                   bool /*a_has_frame*/,
+                   const IDebugger::Frame &a_frame,
+                   int /*a_thread_id*/,
+                   int /*a_bp_num*/,
+                   const UString &/*a_cookie*/,
+                   IDebuggerSafePtr &a_debugger)
+{
+    MESSAGE ("stopped at: "
+             << a_frame.function_name ()
+             << ":"
+             << a_frame.line ());
+
+    if (a_reason == IDebugger::BREAKPOINT_HIT) {
+        a_debugger->step_over ();
+    } else if (a_reason == IDebugger::END_STEPPING_RANGE) {
+        a_debugger->create_variable ("person",
+                                     sigc::bind (&on_variable_created,
+                                                 a_debugger));
+    } else {
+        a_debugger->do_continue ();
+    }
+}
+
+NEMIVER_API int
+test_main (int argc, char *argv[])
+{
+    if (argc || argv) {/*keep compiler happy*/}
+
+    NEMIVER_TRY
+
+    Initializer::do_init () ;
+
+    THROW_IF_FAIL (loop) ;
+
+    DynamicModuleManager module_manager ;
+    IDebuggerSafePtr debugger =
+            module_manager.load_iface<IDebugger> ("gdbengine", "IDebugger");
+
+    debugger->set_event_loop_context (loop->get_context ()) ;
+
+    //*****************************
+    //<connect to IDebugger events>
+    //*****************************
+    debugger->engine_died_signal ().connect (&on_engine_died_signal) ;
+
+    debugger->program_finished_signal ().connect
+                                            (&on_program_finished_signal) ;
+
+    debugger->breakpoints_set_signal ().connect
+                                            (&on_breakpoints_set_signal) ;
+
+    debugger->stopped_signal ().connect (sigc::bind (&on_stopped_signal,
+                                                     debugger));
+
+    std::vector<UString> args, source_search_dir ;
+    args.push_back ("fooprog") ;
+    source_search_dir.push_back (".") ;
+
+    debugger->load_program (args, "", source_search_dir);
+    debugger->set_breakpoint ("main") ;
+    debugger->run () ;
+    loop->run () ;
+
+    NEMIVER_CATCH_NOX
+
+    return 0 ;
+}
+
+#endif // WITH_VAROBJS
+



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