[PATCH] Support GDB/MI properties displayint, dynamic, has_more



I was hacking on bug "657834 - Issues the new pretty printing code"
and Tom Tromey made me notice[1] that for dynamic variable objects
(like those used when pretty printing is enabled), when we look at the
tuples resulting from the -var-list-children MI command, we should not
look at the 'numchild' result because it's not reliable for dynamic
varobjs.

Rather, we should be looking at the 'has_more' result.

The issue here is that Nemiver's GDB/MI parser was dropping the
'has_more' result on the floor, along with a couple of other results.

On top of that, the IDebugger::Variable::has_expected_children method
(what I clunky name!) that the debugging perspective of Nemiver uses
to know whether if a given variable has children or not was
(obviously) looking at the 'numchild' result.  As a result, Nemiver
was failing to let the user unfold a pretty printed container from
libstdc++.

This patch does several things:

* it parses the results (or properties) "dynamic", "has_more" and
  "displayint" that it was previously dropping on the floor.
* it changes the IDebugger::Variable::has_expected_children method
  name into IDebugger::Variable::expects_children and makes it look at
  the 'has_more' property whenever the variable is dynamic.

So this patch partially fixes bug 657834 as it now lets the user
unfold pretty printed container variables from libstdc++.  I say
'partially' because other problems remain; I'll talk about those in
subsequent patch emails.

Tested and applied to master.

[1]: http://sourceware.org/bugzilla/show_bug.cgi?id=13149

commit 7df48d843c944998c880561538b3af91262eb2b2
Author: Dodji Seketeli <dodji seketeli org>
Date:   Sat Feb 4 15:47:56 2012 +0100

    Support GDB/MI properties displayint, dynamic, has_more
    
    	* src/dbgengine/nmv-i-debugger.h
    	(IDebugger::{m_display_hint,m_is_dynamic,m_has_more_children}):
    	New members.
    	(Variable::Variable): Initialize the new members.
    	(Variable::{display_hint,is_dynamic,has_more_children}): New
    	accessors.
    	(Variable::expects_children): Renamed
    	Variable::has_expected_children into this.  Use the new
    	Variable::has_more_children accessor.
    	(Variable::needs_unfolding): Adjust.
    	* src/dbgengine/nmv-gdbmi-parser.cc (GDBMIParser::parse_variable):
    	Support "displayhinr", "dynamic", "has_more" properties.
    	* tests/test-vars.cc (on_variable_unfolded_signal): Adjust.

diff --git a/src/dbgengine/nmv-gdbmi-parser.cc b/src/dbgengine/nmv-gdbmi-parser.cc
index c0e3b29..3462f8a 100644
--- a/src/dbgengine/nmv-gdbmi-parser.cc
+++ b/src/dbgengine/nmv-gdbmi-parser.cc
@@ -4323,6 +4323,12 @@ GDBMIParser::parse_variable (UString::size_type a_from,
             LOG_D ("num children: " << s, GDBMI_PARSING_DOMAIN);
         } else if (result->variable () == "type") {
             var->type (value);
+        } else if (result->variable () == "displayint") {
+            var->display_hint (value);
+        } else if (result->variable () == "dynamic") {
+            var->is_dynamic ((value == "0" ) ? false: true);
+        } else if (result->variable () == "has_more") {
+            var->has_more_children ((value == "0") ? false : true);
         } else {
             LOG_D ("hugh? unknown result variable: " << result->variable (),
                    GDBMI_PARSING_DOMAIN);
diff --git a/src/dbgengine/nmv-i-debugger.h b/src/dbgengine/nmv-i-debugger.h
index 56bea4a..39dc248 100644
--- a/src/dbgengine/nmv-i-debugger.h
+++ b/src/dbgengine/nmv-i-debugger.h
@@ -402,6 +402,7 @@ public:
         // disabled the variable would be displayed using no pretty
         // printer.
         UString m_visualizer;
+        UString m_display_hint;
         Variable *m_parent;
         //if this variable is a pointer,
         //it can be dereferenced. The variable
@@ -416,6 +417,8 @@ public:
         bool m_in_scope;
         Format m_format;
         bool m_needs_revisualizing;
+        bool m_is_dynamic;
+        bool m_has_more_children;
 
     public:
         Variable (const UString &a_internal_name,
@@ -433,7 +436,9 @@ public:
             m_num_expected_children (0),
             m_in_scope (a_in_scope),
             m_format (UNDEFINED_FORMAT),
-            m_needs_revisualizing (false)
+            m_needs_revisualizing (false),
+            m_is_dynamic (false),
+            m_has_more_children (false)
         {
         }
 
@@ -450,7 +455,9 @@ public:
             m_num_expected_children (0),
             m_in_scope (a_in_scope),
             m_format (UNDEFINED_FORMAT),
-            m_needs_revisualizing (false)
+            m_needs_revisualizing (false),
+            m_is_dynamic (false),
+            m_has_more_children (false)
 
         {
         }
@@ -463,7 +470,10 @@ public:
             m_num_expected_children (0),
             m_in_scope (true),
             m_format (UNDEFINED_FORMAT),
-            m_needs_revisualizing (false)
+            m_needs_revisualizing (false),
+            m_is_dynamic (false),
+            m_has_more_children (false)
+
         {
         }
 
@@ -473,7 +483,9 @@ public:
             m_num_expected_children (0),
             m_in_scope (true),
             m_format (UNDEFINED_FORMAT),
-            m_needs_revisualizing (false)
+            m_needs_revisualizing (false),
+                    m_is_dynamic (false),
+            m_has_more_children (false)
         {
         }
 
@@ -607,6 +619,9 @@ public:
         const UString& visualizer () const {return m_visualizer;}
         void visualizer (const UString &a) {m_visualizer = a;}
 
+        const UString& display_hint () const {return m_display_hint;};
+        void display_hint (const UString &a) {m_display_hint = a;}
+
         /// Return true if this instance of Variable has a parent variable,
         /// false otherwise.
         bool has_parent () const
@@ -796,16 +811,17 @@ public:
             m_num_expected_children = a_in;
         }
 
-        bool has_expected_children () const
+        bool expects_children () const
         {
-            return m_num_expected_children != 0;
+            return ((m_num_expected_children != 0)
+                    || (has_more_children ()));
         }
 
         /// \return true if the current variable needs to be unfolded
         /// by a call to IDebugger::unfold_variable()
         bool needs_unfolding () const
         {
-            return (has_expected_children () && members ().empty ());
+            return (expects_children () && members ().empty ());
         }
 
         /// Return the descendant of the current instance of Variable.
@@ -851,6 +867,12 @@ public:
         bool needs_revisualizing () const {return m_needs_revisualizing;}
         void needs_revisualizing (bool a) {m_needs_revisualizing = a;}
 
+        bool is_dynamic () const {return m_is_dynamic;}
+        void is_dynamic (bool a) {m_is_dynamic = a;}
+
+        bool has_more_children () const {return m_has_more_children;}
+        void has_more_children (bool a) {m_has_more_children = a;}
+
     };//end class Variable
 
     enum State {
diff --git a/tests/test-vars.cc b/tests/test-vars.cc
index bb1a017..6593bd0 100644
--- a/tests/test-vars.cc
+++ b/tests/test-vars.cc
@@ -145,7 +145,7 @@ on_variable_unfolded_signal (const IDebugger::VariableSafePtr a_var,
     for (VarIter it = a_var->members ().begin ();
          it != a_var->members ().end ();
          ++it) {
-        if ((*it)->has_expected_children ()) {
+        if ((*it)->expects_children ()) {
             unfold_requests++;
             a_debugger->unfold_variable (*it,
                                          sigc::bind (&on_variable_unfolded_signal,

-- 
		Dodji


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