[nemiver/better-variable-format: 1/9] Backend support for GDB/MI variable format



commit 30b633864e5075732606611f8a5de686b80edde8
Author: Dodji Seketeli <dodji gnome org>
Date:   Mon Aug 30 11:15:55 2010 +0200

    Backend support for GDB/MI variable format
    
    	* src/dbgengine/nmv-gdbmi-parser.h (parse_variable_format):
    	Declare new GDBMI parser entry point.
    	* src/dbgengine/nmv-gdbmi-parser.cc (parse_variable_format):
    	Define it.
    	(parse_result_record): Support variable format result record. Use
    	parse_variable_format.
    	* src/dbgengine/nmv-i-debugger.h (IDebugger::Variable::Format):
    	New enum.
    	(query_variable_format, set_variable_format): Declare new entry
    	points.
    	* src/dbgengine/nmv-dbg-common.h (ResultRecord::variable_format)
    	(ResultRecord::has_variable_format): New accessors to support
    	variable format in the result record.
    	* src/dbgengine/nmv-debugger-utils.[cc|h] (string_to_variable_format)
    	(variable_format_to_string): New (de)serialization functions.
    	* src/dbgengine/nmv-gdb-engine.h (query_variable_format)
    	(set_variable_format): Likewise.
    	* src/dbgengine/nmv-gdb-engine.cc (query_variable_format)
    	(set_variable_format): Define these.
    	(struct OnVariableFormatHandler): New output handler.
    	(init_output_handlers): Add it to the list of output handlers.
    	* src/dbgengine/Makefile.am: Make the libgdbmod use the static lib
    	libdebuggerutils.
    	* tests/test-variable-format.cc: New test.
    	* tests/Makefile.am: Added new test-variable-format to the build
    	system. Link runtestgdbmi and runtestvarobjwalker with
    	libdebuggerutils.la
    	* tests/fooprog.cc: Add a new func1_1 to test for some variable
    	value. Used by the new tests/test-variable-format.cc.

 src/dbgengine/Makefile.am           |    4 +-
 src/dbgengine/nmv-dbg-common.h      |   25 ++++++
 src/dbgengine/nmv-debugger-utils.cc |   57 +++++++++++++
 src/dbgengine/nmv-debugger-utils.h  |    4 +
 src/dbgengine/nmv-gdb-engine.cc     |   93 ++++++++++++++++++++++
 src/dbgengine/nmv-gdb-engine.h      |    8 ++
 src/dbgengine/nmv-gdbmi-parser.cc   |   76 ++++++++++++++++++
 src/dbgengine/nmv-gdbmi-parser.h    |    5 +
 src/dbgengine/nmv-i-debugger.h      |   27 ++++++-
 tests/Makefile.am                   |   14 +++-
 tests/fooprog.cc                    |    9 ++-
 tests/test-variable-format.cc       |  149 +++++++++++++++++++++++++++++++++++
 12 files changed, 464 insertions(+), 7 deletions(-)
---
diff --git a/src/dbgengine/Makefile.am b/src/dbgengine/Makefile.am
index c4e73cd..4ad7d19 100644
--- a/src/dbgengine/Makefile.am
+++ b/src/dbgengine/Makefile.am
@@ -93,8 +93,8 @@ publicheaders_DATA=$(dynmodheaders)
 publicheadersdir=$(NEMIVER_INCLUDE_DIR)/dynmods
 
 libgdbmod_la_LDFLAGS=-module -avoid-version -Wl,--as-needed
-libgdbmod_la_LIBADD=libdbgcommon.la libgdbmiparser.la libgdbengine.la \
- NEMIVERCOMMON_LIBS@ \
+libgdbmod_la_LIBADD=libdbgcommon.la libgdbmiparser.la \
+libgdbengine.la libdebuggerutils.la @NEMIVERCOMMON_LIBS@ \
 $(top_builddir)/src/langs/libnemivercparser.la \
 $(top_builddir)/src/common/libnemivercommon.la
 
diff --git a/src/dbgengine/nmv-dbg-common.h b/src/dbgengine/nmv-dbg-common.h
index 0cbe9ea..14c1e44 100644
--- a/src/dbgengine/nmv-dbg-common.h
+++ b/src/dbgengine/nmv-dbg-common.h
@@ -429,6 +429,10 @@ public:
         UString m_path_expression;
         bool m_has_path_expression;
 
+        // The variable format of a variable object
+        IDebugger::Variable::Format m_variable_format;
+        bool m_has_variable_format;
+
     public:
         ResultRecord () {clear ();}
 
@@ -471,6 +475,8 @@ public:
             m_has_changed_var_list = false;
             m_path_expression.clear ();
             m_has_path_expression = false;
+            m_variable_format = IDebugger::Variable::UNDEFINED_FORMAT;
+            m_has_variable_format = false;
         }
 
         /// \name accessors
@@ -746,6 +752,25 @@ public:
             m_has_path_expression = a;
         }
 
+        IDebugger::Variable::Format variable_format () const
+        {
+            return m_variable_format;
+        }
+        void variable_format (IDebugger::Variable::Format a_format)
+        {
+            m_variable_format = a_format;
+            has_variable_format (true);
+        }
+
+        bool has_variable_format () const
+        {
+            return m_has_variable_format;
+        }
+        void has_variable_format (bool a_flag)
+        {
+            m_has_variable_format = a_flag;
+        }
+
         /// @}
 
     };//end class ResultRecord
diff --git a/src/dbgengine/nmv-debugger-utils.cc b/src/dbgengine/nmv-debugger-utils.cc
index 5970a76..14d43f4 100644
--- a/src/dbgengine/nmv-debugger-utils.cc
+++ b/src/dbgengine/nmv-debugger-utils.cc
@@ -85,5 +85,62 @@ dump_variable_value (IDebugger::VariableSafePtr a_var,
     a_out_str = os.str ();
 }
 
+/// Read a string and convert it into the IDebugger::Variable::Format
+/// enum.
+/// \param a_str the string to consider
+/// \return resulting format enum
+IDebugger::Variable::Format
+string_to_variable_format (const std::string &a_str)
+{
+    IDebugger::Variable::Format result =
+        IDebugger::Variable::UNKNOWN_FORMAT;
+
+    if (a_str == "binary") {
+        result = IDebugger::Variable::BINARY_FORMAT;
+    } else if (a_str == "decimal") {
+        result = IDebugger::Variable::DECIMAL_FORMAT;
+    } else if (a_str == "hexadecimal") {
+        result = IDebugger::Variable::HEXADECIMAL_FORMAT;
+    } else if (a_str == "octal") {
+        result = IDebugger::Variable::OCTAL_FORMAT;
+    } else if (a_str == "natural") {
+        result = IDebugger::Variable::NATURAL_FORMAT;
+    }
+    return result;
+}
+
+/// Serialize an IDebugger::Variable::Format enum into a string.
+/// \param a_format the instance of format to serialize.
+/// \return the resulting serialization.
+std::string
+variable_format_to_string (IDebugger::Variable::Format a_format)
+{
+    std::string result;
+    switch (a_format) {
+    case IDebugger::Variable::UNDEFINED_FORMAT:
+        result = "undefined";
+        break;
+    case IDebugger::Variable::BINARY_FORMAT:
+        result = "binary";
+        break;
+    case IDebugger::Variable::DECIMAL_FORMAT:
+        result = "decimal";
+        break;
+    case IDebugger::Variable::HEXADECIMAL_FORMAT:
+        result = "hexadecimal";
+        break;
+    case IDebugger::Variable::OCTAL_FORMAT:
+        result = "octal";
+        break;
+    case IDebugger::Variable::NATURAL_FORMAT:
+        result = "natural";
+        break;
+    case IDebugger::Variable::UNKNOWN_FORMAT:
+        result = "unknown";
+        break;
+    }
+    return result;
+}
+
 NEMIVER_END_NAMESPACE (debugger_utils)
 NEMIVER_END_NAMESPACE (nemiver)
diff --git a/src/dbgengine/nmv-debugger-utils.h b/src/dbgengine/nmv-debugger-utils.h
index 125368c..61f4265 100644
--- a/src/dbgengine/nmv-debugger-utils.h
+++ b/src/dbgengine/nmv-debugger-utils.h
@@ -41,6 +41,10 @@ void dump_variable_value (IDebugger::VariableSafePtr a_var,
                           int a_indent_num,
                           std::string &a_out_str);
 
+IDebugger::Variable::Format string_to_variable_format (const std::string &);
+
+std::string variable_format_to_string (IDebugger::Variable::Format);
+
 NEMIVER_END_NAMESPACE (debugger_utils)
 NEMIVER_END_NAMESPACE (nemiver)
 
diff --git a/src/dbgengine/nmv-gdb-engine.cc b/src/dbgengine/nmv-gdb-engine.cc
index dfd4b7b..8420e9b 100644
--- a/src/dbgengine/nmv-gdb-engine.cc
+++ b/src/dbgengine/nmv-gdb-engine.cc
@@ -43,6 +43,7 @@
 #include "langs/nmv-cpp-parser.h"
 #include "langs/nmv-cpp-ast-utils.h"
 #include "nmv-i-lang-trait.h"
+#include "nmv-debugger-utils.h"
 
 using namespace std;
 using namespace nemiver::common;
@@ -2569,6 +2570,45 @@ struct OnListChangedVariableHandler : public OutputHandler {
     }
 };//end OnListChangedVariableHandler
 
+struct OnVariableFormatHandler : public OutputHandler
+{
+    GDBEngine *m_engine;
+
+    OnVariableFormatHandler (GDBEngine *a_engine) :
+        m_engine (a_engine)
+    {
+    }
+
+    bool can_handle (CommandAndOutput &a_in)
+    {
+        if (a_in.command ().name () == "query-variable-format"
+            && a_in.output ().result_record ().kind ()
+               == Output::ResultRecord::DONE) {
+            return true;
+        }
+        return false;
+    }
+
+    void do_handle (CommandAndOutput &a_in)
+    {
+        if (a_in.command ().name () == "query-variable-format"
+            && a_in.output ().result_record ().has_variable_format ()) {
+            // Set the result we got from gdb into the variable handed to us
+            // by the the client code.
+            a_in.command ().variable ()->format
+                (a_in.output ().result_record ().variable_format ());
+
+            // Call the slot associated to
+            // IDebugger::query_variable_format.
+            if (a_in.command ().has_slot ()) {
+                typedef IDebugger::ConstVariableSlot SlotType;
+                SlotType slot = a_in.command ().get_slot<SlotType> ();
+                slot (a_in.command ().variable ());
+            }
+        }
+    }
+};//end OnVariableFormatHandler
+
 //****************************
 //</GDBengine output handlers
 //***************************
@@ -2923,6 +2963,8 @@ GDBEngine::init_output_handlers ()
             (OutputHandlerSafePtr (new OnUnfoldVariableHandler (this)));
     m_priv->output_handler_list.add
             (OutputHandlerSafePtr (new OnListChangedVariableHandler (this)));
+    m_priv->output_handler_list.add
+            (OutputHandlerSafePtr (new OnVariableFormatHandler (this)));
 }
 
 sigc::signal<void, Output&>&
@@ -4820,6 +4862,57 @@ GDBEngine::query_variable_path_expr (const VariableSafePtr a_var,
     queue_command (command);
 }
 
+/// Ask GDB what the value display format of a variable is.
+/// \param a_var the variable to consider
+/// \param a_slot the slot to invoke upon receiving the reply from
+/// GDB.
+/// \param a_cookie the cookie of this request
+void
+GDBEngine::query_variable_format (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-show-format ";
+    cmd_str += a_var->internal_name ();
+
+    Command command ("query-variable-format",
+                     cmd_str, a_cookie);
+    command.variable (a_var);
+    command.set_slot (a_slot);
+    queue_command (command);
+}
+
+/// Set the value display format of variable a_var
+/// \param a_var the variable to consider
+/// \param a_format the format to set the display format of the
+/// variable to.
+/// \param a_cookie the cookie of this request.
+void
+GDBEngine::set_variable_format (const VariableSafePtr a_var,
+				const Variable::Format a_format,
+				const UString &a_cookie)
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+    THROW_IF_FAIL (a_var);
+    THROW_IF_FAIL (!a_var->internal_name ().empty ());
+    THROW_IF_FAIL (a_format > IDebugger::Variable::UNDEFINED_FORMAT
+                   && a_format < IDebugger::Variable::UNKNOWN_FORMAT);
+
+    UString cmd_str = "-var-set-format ";
+    cmd_str +=
+        a_var->internal_name () + " " +
+        debugger_utils::variable_format_to_string (a_format);
+    Command command ("set-variable-format",
+                     cmd_str, a_cookie);
+    queue_command (command);
+}
+
 //****************************
 //</GDBEngine methods>
 //****************************
diff --git a/src/dbgengine/nmv-gdb-engine.h b/src/dbgengine/nmv-gdb-engine.h
index cd36ef1..f804b03 100644
--- a/src/dbgengine/nmv-gdb-engine.h
+++ b/src/dbgengine/nmv-gdb-engine.h
@@ -533,6 +533,14 @@ public:
     void query_variable_path_expr (const VariableSafePtr,
                                    const ConstVariableSlot &a_slot,
                                    const UString &a_cookie);
+
+    void query_variable_format (const VariableSafePtr a_var,
+                                const ConstVariableSlot &a_slot,
+                                const UString &a_cookie);
+
+    void set_variable_format (const VariableSafePtr a_var,
+			      const Variable::Format a_format,
+			      const UString &a_cookie);
 };//end class GDBEngine
 
 NEMIVER_END_NAMESPACE (nemiver)
diff --git a/src/dbgengine/nmv-gdbmi-parser.cc b/src/dbgengine/nmv-gdbmi-parser.cc
index ce4236d..844fa7d 100644
--- a/src/dbgengine/nmv-gdbmi-parser.cc
+++ b/src/dbgengine/nmv-gdbmi-parser.cc
@@ -26,7 +26,9 @@
 #include <cstring>
 #include <sstream>
 #include "common/nmv-str-utils.h"
+#include "common/nmv-asm-utils.h"
 #include "nmv-gdbmi-parser.h"
+#include "nmv-debugger-utils.h"
 
 using nemiver::common::UString;
 
@@ -194,6 +196,7 @@ const char* CHANGELIST = "changelist";
 const char* PREFIX_PATH_EXPR = "path_expr=";
 const char* PATH_EXPR = "path_expr";
 static const char* PREFIX_ASM_INSTRUCTIONS= "asm_insns=";
+const char* PREFIX_VARIABLE_FORMAT = "format=";
 
 static bool
 is_string_start (gunichar a_c)
@@ -2011,6 +2014,22 @@ fetch_gdbmi_result:
                 } else {
                     LOG_PARSING_ERROR2 (cur);
                 }
+            } else if (!RAW_INPUT.compare (cur,
+                                           strlen (PREFIX_VARIABLE_FORMAT),
+                                           PREFIX_VARIABLE_FORMAT)) {
+                IDebugger::Variable::Format format =
+                            IDebugger::Variable::UNDEFINED_FORMAT;
+                UString value;
+                if (parse_variable_format (cur, cur, format, value)) {
+                    result_record.variable_format (format);
+                    if (!value.empty ()) {
+                        IDebugger::VariableSafePtr var (new IDebugger::Variable);
+                        var->value (value);
+                        result_record.variable_value (var);
+                    }
+                } else {
+                    LOG_PARSING_ERROR2 (cur);
+                }
             } else {
                 GDBMIResultSafePtr result;
                 if (!parse_gdbmi_result (cur, cur, result)
@@ -3631,6 +3650,63 @@ GDBMIParser::parse_var_path_expression (UString::size_type a_from,
 }
 
 bool
+GDBMIParser::parse_variable_format (UString::size_type a_from,
+                                    UString::size_type &a_to,
+                                    IDebugger::Variable::Format &a_format,
+                                    UString &a_value)
+{
+    LOG_FUNCTION_SCOPE_NORMAL_D (GDBMI_PARSING_DOMAIN);
+    UString::size_type cur = a_from;
+    CHECK_END2 (cur);
+
+    if (RAW_INPUT.compare (cur, strlen (PREFIX_VARIABLE_FORMAT),
+                           PREFIX_VARIABLE_FORMAT)) {
+        LOG_PARSING_ERROR2 (cur);
+        return false;
+    }
+
+    UString name, value;
+    if (!parse_gdbmi_string_result (cur, cur, name, value)) {
+        LOG_PARSING_ERROR2 (cur);
+        return false;
+    }
+    const char *FORMAT = "format";
+    if (name != FORMAT) {
+        LOG_ERROR ("expected gdbmi variable " << FORMAT << ", got: "
+                   << name << "\'");
+        return false;
+    }
+
+    a_format = debugger_utils::string_to_variable_format (value);
+    if (a_format == IDebugger::Variable::UNKNOWN_FORMAT) {
+        LOG_ERROR ("got unknown variable format: '" << a_format << "'");
+        return false;
+    }
+
+    SKIP_WS2 (cur);
+    if (RAW_CHAR_AT (cur) == ',') {
+        ++cur;
+        SKIP_WS2 (cur);
+        name.clear (), value.clear ();
+        if (!parse_gdbmi_string_result (cur, cur, name, value)) {
+            LOG_PARSING_ERROR2 (cur);
+            return false;
+        }
+        const char *VALUE = "value";
+        if (name == VALUE) {
+            if (value.empty ()) {
+                LOG_ERROR ("the 'value' property should have a non-empty value");
+                return true;
+            }
+            a_value = value;
+        }
+    }
+
+    a_to = cur;
+    return true;
+}
+
+bool
 GDBMIParser::parse_register_names (UString::size_type a_from,
                                    UString::size_type &a_to,
                                    std::map<IDebugger::register_id_t,
diff --git a/src/dbgengine/nmv-gdbmi-parser.h b/src/dbgengine/nmv-gdbmi-parser.h
index 32ddf9e..c9c2ae4 100644
--- a/src/dbgengine/nmv-gdbmi-parser.h
+++ b/src/dbgengine/nmv-gdbmi-parser.h
@@ -639,6 +639,11 @@ public:
                                     UString::size_type &a_to,
                                     UString &a_expression);
 
+    bool parse_variable_format (UString::size_type a_from,
+                                UString::size_type &a_to,
+                                IDebugger::Variable::Format &a_format,
+                                UString &a_value);
+
     bool parse_result_record (UString::size_type a_from,
                               UString::size_type &a_to,
                               Output::ResultRecord &a_record);
diff --git a/src/dbgengine/nmv-i-debugger.h b/src/dbgengine/nmv-i-debugger.h
index 101573c..dc135f4 100644
--- a/src/dbgengine/nmv-i-debugger.h
+++ b/src/dbgengine/nmv-i-debugger.h
@@ -328,6 +328,17 @@ public:
     typedef SafePtr<Variable, ObjectRef, ObjectUnref> VariableSafePtr;
     typedef list<VariableSafePtr> VariableList;
     class Variable : public Object {
+    public:
+        enum Format {
+            UNDEFINED_FORMAT = 0,
+            BINARY_FORMAT,
+            DECIMAL_FORMAT,
+            HEXADECIMAL_FORMAT,
+            OCTAL_FORMAT,
+            NATURAL_FORMAT,
+            UNKNOWN_FORMAT // must be last
+        };
+    private:
         // non copyable.
         Variable (const Variable &);
         Variable& operator= (const Variable &);
@@ -355,6 +366,7 @@ public:
         // If empty, it can be set by calling
         // IDebugger::query_variable_path_expr()
         UString m_path_expression;
+        Format m_format;
 
     public:
         Variable (const UString &a_internal_name,
@@ -366,7 +378,8 @@ public:
             m_value (a_value),
             m_type (a_type),
             m_parent (0),
-            m_num_expected_children (0)
+            m_num_expected_children (0),
+            m_format (UNDEFINED_FORMAT)
 
         {
         }
@@ -735,6 +748,10 @@ public:
         {
             m_path_expression = a_expr;
         }
+
+        Format format () const {return m_format;}
+        void format (Format a_format) {m_format = a_format;}
+
     };//end class Variable
 
     enum State {
@@ -1276,10 +1293,18 @@ public:
 
     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;
 
+    virtual void query_variable_format (const VariableSafePtr a_var,
+                                        const ConstVariableSlot &a_slot,
+                                        const UString &a_cookie = "") = 0;
+
+    virtual void set_variable_format (const VariableSafePtr a_var,
+                                      const Variable::Format a_format,
+                                      const UString &a_cookie = "") = 0;
 };//end IDebugger
 
 NEMIVER_END_NAMESPACE (nemiver)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f720cea..2b179c6 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -12,7 +12,8 @@ runtestwatchpoint runtestderef \
 runtestlocalvarslist runtestcpplexer \
 runtestcppparser runtestvarpathexpr \
 runtestlibtoolwrapperdetection \
-runtestenv runtesttypes runtestdisassemble
+runtestenv runtesttypes runtestdisassemble \
+runtestvariableformat
 
 else
 
@@ -31,7 +32,8 @@ runtestgdbmi_SOURCES=test-gdbmi.cc
 runtestgdbmi_LDADD= @NEMIVERCOMMON_LIBS@ \
 @BOOST_UNIT_TEST_FRAMEWORK_STATIC_LIB@ \
 $(top_builddir)/src/common/libnemivercommon.la \
-$(top_builddir)/src/dbgengine/libgdbmiparser.la
+$(top_builddir)/src/dbgengine/libgdbmiparser.la \
+$(top_builddir)/src/dbgengine/libdebuggerutils.la
 
 gtkmmtest_SOURCES=gtkmm-test.cc
 gtkmmtest_CXXFLAGS= @NEMIVERUICOMMON_CFLAGS@
@@ -60,7 +62,13 @@ $(top_builddir)/src/common/libnemivercommon.la
 
 runtestvarobjwalker_SOURCES=test-varobj-walker.cc
 runtestvarobjwalker_LDADD= NEMIVERCOMMON_LIBS@ @BOOST_TEST_EXEC_MONITOR_LIB@ \
-$(top_builddir)/src/common/libnemivercommon.la
+$(top_builddir)/src/common/libnemivercommon.la \
+$(top_builddir)/src/dbgengine/libdebuggerutils.la
+
+runtestvariableformat_SOURCES=test-variable-format.cc
+runtestvariableformat_LDADD= NEMIVERCOMMON_LIBS@ @BOOST_TEST_EXEC_MONITOR_LIB@ \
+$(top_builddir)/src/common/libnemivercommon.la \
+$(top_builddir)/src/dbgengine/libdebuggerutils.la
 
 #runtestoverloads_SOURCES=test-overloads.cc
 #runtestoverloads_LDADD= NEMIVERCOMMON_LIBS@ @BOOST_TEST_EXEC_MONITOR_LIB@ \
diff --git a/tests/fooprog.cc b/tests/fooprog.cc
index 430af63..61bdb96 100644
--- a/tests/fooprog.cc
+++ b/tests/fooprog.cc
@@ -2,10 +2,17 @@
 #include <iostream>
 
 void
+func1_1 (int i_i)
+{
+  ++i_i;
+}
+
+void
 func1 ()
 {
-    int i = 0;
+    int i = 17;
     ++i;
+    func1_1 (i);
 }
 
 void
diff --git a/tests/test-variable-format.cc b/tests/test-variable-format.cc
new file mode 100644
index 0000000..745eb1c
--- /dev/null
+++ b/tests/test-variable-format.cc
@@ -0,0 +1,149 @@
+#include <iostream>
+#include <sstream>
+#include <map>
+#include <string>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/minimal.hpp>
+#include <glibmm.h>
+#include "common/nmv-initializer.h"
+#include "common/nmv-exception.h"
+#include "nmv-i-var-list-walker.h"
+
+using namespace nemiver;
+using namespace nemiver::common;
+
+Glib::RefPtr<Glib::MainLoop> s_loop =
+    Glib::MainLoop::create (Glib::MainContext::get_default ());
+
+static bool s_got_format;
+static bool s_got_value;
+
+static void
+on_engine_died_signal ()
+{
+    s_loop->quit ();
+}
+
+static void
+on_program_finished_signal ()
+{
+    s_loop->quit ();
+}
+
+static void
+on_var_format (const IDebugger::VariableSafePtr a_var,
+	       IDebuggerSafePtr /*a_debugger*/)
+{
+    BOOST_REQUIRE (a_var);
+    BOOST_REQUIRE (a_var->format () ==
+		   IDebugger::Variable::HEXADECIMAL_FORMAT);
+    s_got_format = true;
+}
+
+static void
+on_var_evaluated (const IDebugger::VariableSafePtr a_var,
+		  IDebuggerSafePtr /*a_debugger*/)
+{
+    BOOST_REQUIRE (a_var);
+    BOOST_REQUIRE (a_var->format () ==
+		   IDebugger::Variable::HEXADECIMAL_FORMAT);
+    BOOST_REQUIRE (a_var->value () == "0x12");
+    s_got_value = true;
+    s_loop->quit ();
+}
+
+static void
+on_variable_created (const IDebugger::VariableSafePtr a_var,
+                     IDebuggerSafePtr a_debugger)
+{
+    BOOST_REQUIRE (a_var);
+    BOOST_REQUIRE (a_debugger);
+    a_debugger->step_over ();
+    a_debugger->set_variable_format
+      (a_var, IDebugger::Variable::HEXADECIMAL_FORMAT);
+    a_debugger->query_variable_format (a_var,
+                                       sigc::bind (&on_var_format,
+                                                   a_debugger));
+    a_debugger->evaluate_variable_expr (a_var,
+					sigc::bind
+					(&on_var_evaluated,
+					 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 /*bp num*/,
+                   const UString &/*a_cookie*/,
+                   IDebuggerSafePtr &a_debugger)
+{
+    NEMIVER_TRY
+
+    BOOST_REQUIRE (a_debugger);
+
+    if (a_reason == IDebugger::BREAKPOINT_HIT) {
+        if (a_frame.function_name () == "main") {
+            MESSAGE ("broke in main, setting breakoint "
+		     "into func1_1");
+            a_debugger->set_breakpoint ("func1_1");
+            a_debugger->do_continue ();
+        } else if (a_frame.function_name () == "func1_1") {
+            MESSAGE ("broke in func1_1");
+            a_debugger->create_variable ("i_i",
+                                         sigc::bind
+					 (&on_variable_created,
+					  a_debugger));
+        }
+    } else {
+        a_debugger->do_continue ();
+    }
+
+    NEMIVER_CATCH_NOX
+}
+
+NEMIVER_API int
+test_main (int, char **)
+{
+    NEMIVER_TRY
+
+    Initializer::do_init ();
+
+    //load the IDebugger interface
+    IDebuggerSafePtr debugger =
+        DynamicModuleManager::load_iface_with_default_manager<IDebugger>
+                                                                ("gdbengine",
+                                                                 "IDebugger");
+    //setup the debugger with the glib mainloop
+    debugger->set_event_loop_context (Glib::MainContext::get_default ());
+
+    //*******************************
+    //<connect to IDebugger events>
+    //******************************
+    debugger->engine_died_signal ().connect (&on_engine_died_signal);
+    debugger->program_finished_signal ().connect (&on_program_finished_signal);
+    debugger->stopped_signal ().connect (sigc::bind (&on_stopped_signal,
+                                                     debugger));
+    //*******************************
+    //</connect to IDebugger events>
+    //******************************
+
+    vector<UString> args;
+    debugger->load_program ("fooprog", args, ".");
+    debugger->set_breakpoint ("main");
+
+    debugger->run ();
+
+    //****************************************
+    //run the event loop.
+    //****************************************
+    s_loop->run ();
+
+
+    NEMIVER_CATCH_AND_RETURN_NOX (-1)
+
+    BOOST_REQUIRE (s_got_format);
+
+    return 0;
+}



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