[nemiver/varobjs-support] Beef up variables utils for variable search/updates
- From: Dodji Seketeli <dodji src gnome org>
- To: svn-commits-list gnome org
- Subject: [nemiver/varobjs-support] Beef up variables utils for variable search/updates
- Date: Sat, 18 Apr 2009 15:31:32 -0400 (EDT)
commit a9ee5cb99f8d4e5b679e1200b658f2ff37bb7b69
Author: Dodji Seketeli <dodji redhat com>
Date: Sat Apr 18 20:25:02 2009 +0200
Beef up variables utils for variable search/updates
* src/persp/dbgperspective/nmv-variables-utils.h:
(variables_match, find_a_variable_descendent): Declare new entry
points.
* src/persp/dbgperspective/nmv-variables-utils.cc:
(generate_path_to_descendent): New internal function.
(walk_path_from_row): Likewise.
(find_a_variable_descendent): New function.
(variables_match): New function.
(find_a_variable): During the search, consider all the members
of the variable we are looking for. Use the new variables_match
function for that. Add a comment to this function.
(update_a_variable): Make sure we try to update the proper
descendent variable member of the proper root variable.
Use the new find_a_variable_descendent function for that.
The name of this function might be misleading now. Changing that
belongs to another commit I guess.
---
src/persp/dbgperspective/nmv-variables-utils.cc | 168 +++++++++++++++++++++--
src/persp/dbgperspective/nmv-variables-utils.h | 7 +
2 files changed, 165 insertions(+), 10 deletions(-)
diff --git a/src/persp/dbgperspective/nmv-variables-utils.cc b/src/persp/dbgperspective/nmv-variables-utils.cc
index 40e45a4..97fccbd 100644
--- a/src/persp/dbgperspective/nmv-variables-utils.cc
+++ b/src/persp/dbgperspective/nmv-variables-utils.cc
@@ -189,12 +189,27 @@ update_unfolded_variable (const IDebugger::VariableSafePtr a_var,
}
}
+/// Finds a variable in the tree view of variables.
+/// All the members of the variable are considered
+/// during the search.
+/// \param a_var the variable to find in the tree view
+/// \param a_parent_row_it the graphical row where to start
+// the search from. This function actually starts looking
+// at the chilren rows of this parent row.
+/// \param a_out_row_it the row of the search. This is set
+/// if and only if the function returns true.
+/// \return true upon successful completion, false otherwise.
bool
find_a_variable (const IDebugger::VariableSafePtr a_var,
const Gtk::TreeModel::iterator &a_parent_row_it,
Gtk::TreeModel::iterator &a_out_row_it)
{
- RETURN_VAL_IF_FAIL (a_var && a_parent_row_it, false);
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+ if (!a_var) {
+ LOG_DD ("got null var, returning false");
+ return false;
+ }
Gtk::TreeModel::iterator row_it;
IDebugger::VariableSafePtr var;
@@ -202,21 +217,149 @@ find_a_variable (const IDebugger::VariableSafePtr a_var,
row_it != a_parent_row_it->children ().end ();
++row_it) {
var = row_it->get_value (get_variable_columns ().variable);
- if (!var) {
- LOG_DD ("hit a null variable");
- continue;
- }
- LOG_DD ("reading var: " << var->name ());
- if (var->name ().raw () == a_var->name ().raw ()) {
+ if (variables_match (a_var, row_it)) {
a_out_row_it = row_it;
- return true;
- } else if (find_a_variable (a_var, row_it, a_out_row_it)) {
+ LOG_DD ("found variable");
return true;
}
}
+ LOG_DD ("didn't find variable " << a_var->name ());
return false;
}
+/// Generates a path that addresses a variable descendant
+/// from its root ancestor.
+/// \param a_var the variable descendent to address
+/// \param the resulting path. It's actually a list of index.
+/// Each index is the sibling index of a given level.
+/// e.g. consider the path [0 1 4].
+/// It means a_var is the 5th sibbling child of the 2st sibling child
+/// of the 1nd sibling child of the root ancestor variable.
+/// \return true if a path was generated, false otherwise.
+static bool
+generate_path_to_descendent (IDebugger::VariableSafePtr a_var,
+ list<int> &a_path)
+{
+ if (!a_var)
+ return false;
+ a_path.push_front (a_var->sibling_index ());
+ if (a_var->parent ())
+ return generate_path_to_descendent (a_var->parent (), a_path);
+ return true;
+}
+
+/// Walk a "path to descendent" as the one returned by
+/// generate_path_to_descendent.
+/// The result of the walk is to find the descendent variable member
+/// addressed by the path.
+/// \param a_from the graphical row
+/// (containing the root variable ancestor) to walk from.
+/// \param a_path_start an iterator that points to the beginning of the
+/// path
+/// \param a_path_end an iterator that points to the end of the path
+/// \param a_to the resulting row, if any. This points to the variable
+/// addressed by the path. This parameter is set if and only if the
+/// function returned true.
+/// \return true upon succesful completion, false otherwise.
+static bool
+walk_path_from_row (const Gtk::TreeModel::iterator &a_from,
+ const list<int>::const_iterator &a_path_start,
+ const list<int>::const_iterator &a_path_end,
+ Gtk::TreeModel::iterator &a_to)
+{
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+ if (a_path_start == a_path_end) {
+ if (a_from->parent ()) {
+ a_to = a_from->parent ();
+ return true;
+ }
+ return false;
+ }
+
+ Gtk::TreeModel::iterator row = a_from;
+ for (int steps = 0;
+ steps < *a_path_start && row;
+ ++steps, ++row) {
+ // stepping at the current level;
+ }
+
+ if (!row)
+ // we reached the end of the current level. That means the path
+ // was not well suited for this variable tree view. Bail out.
+ return false;
+
+ // Dive down one level.
+ list<int>::const_iterator from = a_path_start;
+ from++;
+ return walk_path_from_row (row->children ().begin (),
+ from, a_path_end, a_to);
+}
+
+/// Find a member variable that is a descendent of a root ancestor variable
+/// contained in a tree view. This function must actually find the row of the
+/// root ancestor variable in the tree view, and then find the row of
+/// the descendent.
+/// \param a_descendent the descendent to search for.
+/// \param a_parent_row the graphical row from where to start the search.
+/// \param a_out_row the result of the find, if any. This is set if and
+/// only if the function returns true.
+/// \return true upon successful completion, false otherwise.
+bool
+find_a_variable_descendent (const IDebugger::VariableSafePtr a_descendent,
+ const Gtk::TreeModel::iterator &a_parent_row,
+ Gtk::TreeModel::iterator &a_out_row)
+{
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+ if (!a_descendent) {
+ LOG_DD ("got null variable, returning false");
+ return false;
+ }
+
+ // first, find the root variable the descendant belongs to.
+ IDebugger::VariableSafePtr root_var = a_descendent->root ();
+ THROW_IF_FAIL (root_var);
+ Gtk::TreeModel::iterator root_var_row;
+ if (!find_a_variable (root_var, a_parent_row, root_var_row)) {
+ LOG_DD ("didn't find root variable " << root_var->name ());
+ return false;
+ }
+
+ // Now that we have the row of the root variable, look for the
+ // row of the descendent there.
+ // For that, let's get the path to that damn descendent first.
+ list<int> path;
+ generate_path_to_descendent (a_descendent, path);
+
+ // let's walk the path from the root variable down to the descendent
+ // now.
+ if (!walk_path_from_row (root_var_row, path.begin (),
+ path.end (), a_out_row)) {
+ THROW ("fatal: should not be reached");
+ }
+ return true;
+}
+
+/// Tests if a variable matches the variable present on
+/// a tree view node.
+/// \param a_var the variable to consider
+/// \param a_row_it the tree view to test against.
+/// \return true if the a_row_it contains a variable that is
+/// "value-equal" to a_var.
+bool
+variables_match (const IDebugger::VariableSafePtr &a_var,
+ const Gtk::TreeModel::iterator a_row_it)
+{
+ IDebugger::VariableSafePtr var =
+ a_row_it->get_value (get_variable_columns ().variable);
+ if (a_var == var)
+ return true;
+ if (!var || !a_var)
+ return false;
+ return var->equals_by_value (*a_var);
+}
+
bool
update_a_variable (const IDebugger::VariableSafePtr a_var,
const Gtk::TreeView &a_tree_view,
@@ -228,11 +371,16 @@ update_a_variable (const IDebugger::VariableSafePtr a_var,
THROW_IF_FAIL (a_parent_row_it);
Gtk::TreeModel::iterator row_it;
- if (!find_a_variable (a_var, a_parent_row_it, row_it)) {
+ bool found_variable = find_a_variable_descendent (a_var,
+ a_parent_row_it,
+ row_it);
+
+ if (!found_variable) {
LOG_ERROR ("could not find variable in inspector: "
+ a_var->name ());
return false;
}
+
update_a_variable_real (a_var, a_tree_view,
row_it, a_handle_highlight,
a_is_new_frame);
diff --git a/src/persp/dbgperspective/nmv-variables-utils.h b/src/persp/dbgperspective/nmv-variables-utils.h
index 20559d0..6ffe739 100644
--- a/src/persp/dbgperspective/nmv-variables-utils.h
+++ b/src/persp/dbgperspective/nmv-variables-utils.h
@@ -92,6 +92,13 @@ bool find_a_variable (const IDebugger::VariableSafePtr a_var,
const Gtk::TreeModel::iterator &a_parent_row_it,
Gtk::TreeModel::iterator &a_out_row_it);
+bool variables_match (const IDebugger::VariableSafePtr &a_var,
+ const Gtk::TreeModel::iterator a_row_it);
+
+bool find_a_variable_descendent (const IDebugger::VariableSafePtr a_var,
+ const Gtk::TreeModel::iterator &a_parent_row_it,
+ Gtk::TreeModel::iterator &a_out_row_it);
+
bool update_a_variable (const IDebugger::VariableSafePtr a_var,
const Gtk::TreeView &a_tree_view,
Gtk::TreeModel::iterator &a_parent_row_it,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]