This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: RFC: MI - Detecting change of string contents with variable objects
- From: Nick Roberts <nickrob at snap dot net dot nz>
- To: Daniel Jacobowitz <drow at false dot org>
- Cc: Vladimir Prus <ghost at cs dot msu dot su>, gdb-patches at sources dot redhat dot com
- Date: Thu, 4 Jan 2007 17:13:36 +1300
- Subject: Re: RFC: MI - Detecting change of string contents with variable objects
- References: <17797.65268.689590.797944@kahikatea.snap.net.nz> <E1GwCV8-0008SD-TG@zigzag.lvk.cs.msu.su> <17798.19683.251190.740216@kahikatea.snap.net.nz> <200612181136.02429.ghost@cs.msu.su> <20061218133827.GA24800@nevyn.them.org> <17799.3497.476593.138858@kahikatea.snap.net.nz> <20070103224605.GO17935@nevyn.them.org>
> > That's a vary good idea. Here's a revised patch that isn't language
> > dependent. In addition to detecting string contents changes it detects
> > when the output format has changed with -var-set-format. I don't see this
> > as a bad thing and it means that my patch earlier in the year for
> > including the value in the output of -var-set-format probably isn't
> > needed.
>
> Sounds good. I generally agree with Vladimir about reusing
> c_value_of_variable, however.
>
> I believe it is as simple as:
> - Passing a struct value *.
> - Always returning NULL if there is no value, instead of doing
> the struct and array special cases first.
> - Using value_type to get the type code and the number of children.
> - Probably calling value_fetch_lazy first when passing it the new
> value, to avoid the assertions.
I've probably done it the other way round to how you're asking (used
value_get_print_value in c_value_of_variable) but, likewise, it involves
re-use.
> Let me know if you want me to try that myself.
If you approve what I've done that's fine, if not, perhaps you could show me
what you want.
--
Nick http://www.inet.net.nz/~nickrob
2007-01-03 Nick Roberts <nickrob@snap.net.nz>
* varobj.c (struct varobj): New member print_value.
(install_new_value): Compare last printed value with current one
instead of contents.
(new_variable): Initialize var->print_value to NULL.
(free_variable): Free var->print_value.
(value_get_print_value): New function derived from
c_value_of_variable.
(c_value_of_variable): Use value_get_print_value.
*** varobj.c 04 Jan 2007 16:22:25 +1300 1.68
--- varobj.c 04 Jan 2007 17:00:45 +1300
*************** struct varobj
*** 102,107 ****
--- 102,108 ----
/* The type of this variable. This may NEVER be NULL. */
struct type *type;
+
/* The value of this expression or subexpression. This may be NULL.
Invariant: if type_changeable (this) is non-zero, the value is either
NULL, or not lazy. */
*************** struct varobj
*** 127,132 ****
--- 128,136 ----
/* Was this variable updated via a varobj_set_value operation */
int updated;
+
+ /* Last print value */
+ char *print_value;
};
/* Every variable keeps a linked list of its children, described
*************** static int variable_editable (struct var
*** 234,239 ****
--- 238,246 ----
static char *my_value_of_variable (struct varobj *var);
+ static char *value_get_print_value (struct value *value,
+ enum varobj_display_formats format);
+
static int type_changeable (struct varobj *var);
/* C implementation */
*************** install_new_value (struct varobj *var, s
*** 979,1003 ****
else
{
gdb_assert (!value_lazy (var->value));
- gdb_assert (!value_lazy (value));
! if (!value_contents_equal (var->value, value))
! changed = 1;
}
}
}
!
/* We must always keep the new value, since children depend on it. */
if (var->value != NULL)
value_free (var->value);
var->value = value;
var->updated = 0;
!
gdb_assert (!var->value || value_type (var->value));
return changed;
}
-
/* Update the values for a variable and its children. This is a
two-pronged attack. First, re-parse the value for the root's
--- 986,1020 ----
else
{
gdb_assert (!value_lazy (var->value));
! if (var->print_value)
! {
! if (strcmp (var->print_value,
! value_get_print_value (value, var->format)))
! {
! xfree (var->print_value);
! var->print_value =
! xstrdup (value_get_print_value (value, var->format));
! changed = 1;
! }
! }
! else
! var->print_value =
! xstrdup (value_get_print_value (value, var->format));
}
}
}
!
/* We must always keep the new value, since children depend on it. */
if (var->value != NULL)
value_free (var->value);
var->value = value;
var->updated = 0;
!
gdb_assert (!var->value || value_type (var->value));
return changed;
}
/* Update the values for a variable and its children. This is a
two-pronged attack. First, re-parse the value for the root's
*************** new_variable (void)
*** 1470,1475 ****
--- 1487,1493 ----
var->format = 0;
var->root = NULL;
var->updated = 0;
+ var->print_value = NULL;
return var;
}
*************** free_variable (struct varobj *var)
*** 1503,1508 ****
--- 1521,1527 ----
xfree (var->name);
xfree (var->obj_name);
+ xfree (var->print_value);
xfree (var);
}
*************** my_value_of_variable (struct varobj *var
*** 1785,1790 ****
--- 1804,1823 ----
return (*var->root->lang->value_of_variable) (var);
}
+ static char *
+ value_get_print_value (struct value *value, enum varobj_display_formats format)
+ {
+ long dummy;
+ struct ui_file *stb = mem_fileopen ();
+ struct cleanup *old_chain = make_cleanup_ui_file_delete (stb);
+ char *thevalue;
+
+ common_val_print (value, stb, format_code[(int) format], 1, 0, 0);
+ thevalue = ui_file_xstrdup (stb, &dummy);
+ do_cleanups (old_chain);
+ return thevalue;
+ }
+
/* Return non-zero if changes in value of VAR
must be detected and reported by -var-update.
Return zero is -var-update should never report
*************** c_value_of_variable (struct varobj *var)
*** 2153,2171 ****
}
else
{
- long dummy;
- struct ui_file *stb = mem_fileopen ();
- struct cleanup *old_chain = make_cleanup_ui_file_delete (stb);
- char *thevalue;
-
gdb_assert (type_changeable (var));
gdb_assert (!value_lazy (var->value));
! common_val_print (var->value, stb,
! format_code[(int) var->format], 1, 0, 0);
! thevalue = ui_file_xstrdup (stb, &dummy);
! do_cleanups (old_chain);
! return thevalue;
! }
}
}
}
--- 2186,2195 ----
}
else
{
gdb_assert (type_changeable (var));
gdb_assert (!value_lazy (var->value));
! return value_get_print_value (var->value, var->format);
! }
}
}
}