* Patch: implement new dynamic varobj spec
@ 2009-09-10 20:58 Tom Tromey
2009-09-11 5:41 ` Nick Roberts
` (4 more replies)
0 siblings, 5 replies; 39+ messages in thread
From: Tom Tromey @ 2009-09-10 20:58 UTC (permalink / raw)
To: gdb-patches
This is the long-awaited dynamic varobj patch.
It implements the spec as described by Vladimir:
http://sourceware.org/ml/gdb/2009-07/msg00088.html
.. with various minor changes we've discussed on that thread and
elsewhere. I didn't give the follow-up URLs; I think that the doc patch
ought to be sufficient, and if it isn't, I will fix it up.
This has been in development for quite a while, including testing using
two different MI consumers (Vladimir's and one by Noam Yorav-Raphael).
There are three outstanding bugs.
* A dynamic varobj bug that I couldn't reproduce
http://sourceware.org/ml/archer/2009-q3/msg00169.html
* Lazy string printing.
http://sourceware.org/ml/archer/2009-q3/msg00189.html
I'm not sure what we'll do about this in the 7.0 timeframe, maybe
nothing.
* -var-info-path-expression doesn't work
http://sourceware.org/bugzilla/show_bug.cgi?id=10252
(I am not sure it can be made to work, I was planning to turn it into
an error.)
This patch needs a doc review.
This patch doesn't apply directly due to the big python renaming.
You can probably run sed on the patch if you care to try it.
Tom
2009-09-10 Tom Tromey <tromey@redhat.com>
* varobj.h (varobj_update_result_t) <new>: New field.
(varobj_get_child_range, varobj_set_child_range): Declare.
(varobj_list_children): Update.
(varobj_enable_pretty_printing, varobj_has_more)
(varobj_pretty_printed_p): Declare.
* varobj.c (pretty_printing): New global.
(varobj_enable_pretty_printing): New function.
(struct varobj_root) <from, to, constructor, child_iter,
saved_item>: New fields.
(varobj_create): Don't call install_default_visualizer.
(instantiate_pretty_printer): Don't use value_copy.
(varobj_has_more): New function.
(restrict_range): New function.
(install_dynamic_child): Likewise.
(dynamic_varobj_has_child_method): Likewise.
(update_dynamic_varobj_children): Remove 'new_and_unchanged'
argument; add 'new', 'unchanged', and 'to' arguments. Rewrite.
(varobj_get_num_children): Call update_dynamic_varobj_children.
(varobj_list_children): Add 'from' and 'to' arguments. Ignore
result of update_dynamic_varobj_children. Don't call
install_default_visualizer. Restrict result range.
(varobj_add_child): Don't call install_default_visualizer.
(varobj_pretty_printed_p): New function.
(install_visualizer): Rewrite. Move earlier in file.
(install_default_visualizer): Likewise.
(construct_visualizer): New function.
(install_new_value_visualizer): Likewise.
(install_new_value): Don't call release_value. Special case
pretty-printed objects. Use value_incref. Rearrange "changed"
logic.
(varobj_get_child_range): New function.
(varobj_set_child_range): Likewise.
(varobj_set_visualizer): Rewrite.
(varobj_update): Rewrite pretty-printing logic.
(new_variable): Initialize new fields.
(free_variable): Destroy new fields.
(value_of_root): Copy 'from' and 'to'.
(my_value_of_variable): Handle pretty-printers.
(value_get_print_value): Rework pretty-printing logic.
(cplus_describe_child): Don't use release_value.
* mi/mi-cmds.h (mi_cmd_enable_pretty_printing)
(mi_cmd_var_set_update_range): Declare.
* mi/mi-cmds.c (mi_cmds): Add enable-pretty-printing and
var-set-update-range.
* mi/mi-cmd-var.c (print_varobj): Update. Emit "dynamic"
attribute.
(mi_cmd_var_create): Emit "has_more" attribute.
(mi_cmd_var_set_format): Plug memory leak.
(mi_print_value_p): Replace 'type' argument with 'var'. Handle
pretty-printed varobjs.
(mi_cmd_var_list_children): Accept 'from' and 'to' arguments.
Emit "has_more" attribute.
(mi_cmd_var_evaluate_expression): Plug memory leak.
(mi_cmd_var_assign): Likewise.
(varobj_update_one): Likewise. Emit "dynamic", "has_more", and
"new_children" attributes.
(mi_cmd_enable_pretty_printing): New function.
(mi_cmd_var_set_update_range): Likewise.
2009-09-10 Tom Tromey <tromey@redhat.com>
* gdb.texinfo (GDB/MI Variable Objects): Document
-enable-pretty-printing, -var-set-update-range, dynamic varobjs.
Expand -var-update documentation.
2009-09-10 Tom Tromey <tromey@redhat.com>
* lib/mi-support.exp (mi_create_varobj): Update.
(mi_create_floating_varobj): Likewise.
(mi_create_dynamic_varobj): New proc.
(mi_varobj_update): Update.
(mi_varobj_update_with_type_change): Likewise.
(mi_varobj_update_kv_helper): New proc.
(mi_varobj_update_dynamic_helper): Rewrite.
(mi_varobj_update_dynamic): New proc.
(mi_list_varobj_children): Update.
(mi_list_varobj_children_range): Add 'from' and 'to' arguments.
* gdb.python/python-prettyprint.py (pp_outer): New class.
(pp_nullstr): Likewise.
(lookup_function): Register new printers.
* gdb.python/python-prettyprint.c (struct substruct): New type.
(struct outerstruct): Likewise.
(substruct_test): New function.
(struct nullstr): New type.
(string_1, string_2): New globals.
(main): Add new tests.
* gdb.python/python-mi.exp: Added regression tests.
* gdb.mi/mi2-var-display.exp: Update.
* gdb.mi/mi2-var-cmd.exp: Update.
* gdb.mi/mi2-var-child.exp: Update.
* gdb.mi/mi2-var-block.exp: Update.
* gdb.mi/mi-var-invalidate.exp: Update.
* gdb.mi/mi-var-display.exp: Update.
* gdb.mi/mi-var-cmd.exp: Update.
* gdb.mi/mi-var-child.exp: Update.
* gdb.mi/mi-var-block.exp: Update.
* gdb.mi/mi-break.exp: Update.
* gdb.mi/gdb701.exp: Update.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 52ead12..096b3d3 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -23337,6 +23337,8 @@ access this functionality:
@item @strong{Operation}
@tab @strong{Description}
+@item @code{-enable-pretty-printing}
+@tab enable Python-based pretty-printing
@item @code{-var-create}
@tab create a variable object
@item @code{-var-delete}
@@ -23365,6 +23367,8 @@ access this functionality:
@tab update the variable and its children
@item @code{-var-set-frozen}
@tab set frozeness attribute
+@item @code{-var-set-update-range}
+@tab set range of children to display on update
@end multitable
In the next subsection we describe each operation in detail and suggest
@@ -23372,6 +23376,23 @@ how it can be used.
@subheading Description And Use of Operations on Variable Objects
+@subheading The @code{-enable-pretty-printing} Command
+@findex -enable-pretty-printing
+
+@smallexample
+-enable-pretty-printing
+@end smallexample
+
+@value{GDBN} allows Python-based visualizers to affect the output of the
+MI variable object commands. However, because there was no way to
+implement this in a fully backward-compatible way, a front end must
+request that this functionality be enabled.
+
+Once sent, this command cannot be undone.
+
+Note that if Python support has not been compiled into @value{GDBN},
+this command will still succeed.
+
@subheading The @code{-var-create} Command
@findex -var-create
@@ -23411,15 +23432,55 @@ begin with a @samp{*}), or one of the following:
@samp{$@var{regname}} --- a CPU register name
@end itemize
+A varobj's contents may be provided by a Python-based pretty-printer. In this
+case the varobj is known as a @dfn{dynamic varobj}. Dynamic varobjs
+have slightly different semantics in some cases. If the
+@code{-enable-pretty-printing} command is not sent, then @value{GDBN}
+will never create a dynamic varobj. This ensures backward
+compatibility for existing clients.
+
@subsubheading Result
-This operation returns the name, number of children and the type of the
-object created. Type is returned as a string as the ones generated by
-the @value{GDBN} CLI. If a fixed variable object is bound to a
-specific thread, the thread is is also printed:
+This operation returns attributes of the newly-created varobj. These
+include, but are not limited to:
+
+@table @samp
+@item name
+The name of the varobj.
+
+@item numchild
+The number of children of the varobj. This number is not necessarily
+reliable for a dynamic varobj. Instead, you must examine the
+@samp{has_more} attribute.
+
+@item value
+The varobj's scalar value. For a varobj whose type is some sort of
+aggregate (e.g., a @code{struct}), or for a dynamic varobj, this value
+will not be interesting.
+
+@item type
+The varobj's type. This is a string representation of the type, as
+would be printed by the @value{GDBN} CLI.
+
+@item thread-id
+If a fixed variable object is bound to a specific thread, then this is
+the thread's identifier.
+
+@item has_more
+For a dynamic varobj, this indicates whether there appear to be any
+children available. For a non-dynamic varobj, this will be 0.
+
+@item dynamic
+This attribute will be present and have the value @samp{1} if the
+varobj is a dynamic varobj. If the varobj is not a dynamic varobj,
+then this attribute will not be present.
+@end table
+
+Typical output will look like this:
@smallexample
- name="@var{name}",numchild="@var{N}",type="@var{type}",thread-id="@var{M}"
+ name="@var{name}",numchild="@var{N}",type="@var{type}",thread-id="@var{M}",
+ has_more="@var{has_more}"
@end smallexample
@@ -23497,6 +23558,10 @@ Returns the number of children of a variable object @var{name}:
numchild=@var{n}
@end smallexample
+Note that this number is not completely reliable for a dynamic varobj.
+It will return the current number of children, but more children may
+be available.
+
@subheading The @code{-var-list-children} Command
@findex -var-list-children
@@ -23504,7 +23569,7 @@ Returns the number of children of a variable object @var{name}:
@subsubheading Synopsis
@smallexample
- -var-list-children [@var{print-values}] @var{name}
+ -var-list-children [@var{print-values}] @var{name} [@var{from} @var{to}]
@end smallexample
@anchor{-var-list-children}
@@ -23517,6 +23582,22 @@ values; and if it is 2 or @code{--simple-values} print the name and
value for simple data types and just the name for arrays, structures
and unions.
+@var{from} and @var{to}, if specified, indicate the range of children
+to report. If @var{from} or @var{to} is less than zero, the range is
+reset and all children will be reported. Otherwise, children starting
+at @var{from} (zero-based) and ending just before @var{to} will be
+reported.
+
+If a child range is requested, it will not affect the range of
+children reported by a future call to @code{-var-update}. For this,
+you must instead use @code{-var-set-update-range}. The intent of this
+approach is to enable a front end to implement any update approach it
+likes; for example, scrolling a view may cause the front end to
+request more children with @code{-var-list-children}, and then the
+front end could call @code{-var-set-update-range} with a different
+range to ensure that future updates are restricted to just the visible
+items.
+
For each child the following results are returned:
@table @var
@@ -23533,8 +23614,13 @@ designate access qualifiers. For these pseudo children @var{exp} is
@samp{public}, @samp{private}, or @samp{protected}. In this case the
type and value are not present.
+For a dynamic varobj, this value cannot reliably be used to form an
+expression. Also, a dynamic varobj will not report the access
+qualifying pseudo-children, regardless of the language.
+
@item numchild
-Number of children this child has.
+Number of children this child has. For a dynamic varobj, this will be
+0.
@item type
The type of the child.
@@ -23550,6 +23636,19 @@ Otherwise this result is not present.
If the variable object is frozen, this variable will be present with a value of 1.
@end table
+The result may have its own attributes:
+
+@table @samp
+@item displayhint
+A dynamic varobj can supply a display hint to the front end. The
+comes directly from the Python pretty-printer object's
+@code{display_hint} method. @xref{Pretty Printing}.
+
+@item has_more
+This is an integer attribute which is nonzero if there are children
+remaining after the end of the selected range.
+@end table
+
@subsubheading Example
@smallexample
@@ -23626,6 +23725,9 @@ result can be used only for UI presentation. Typical use of
the @code{-var-info-path-expression} command is creating a
watchpoint from a variable object.
+This command is currently not valid for children of a dynamic varobj,
+and will give an error when invoked on one.
+
For example, suppose @code{C} is a C@t{++} class, derived from class
@code{Base}, and that the @code{Base} class has a member called
@code{m_size}. Assume a variable @code{c} is has the type of
@@ -23731,6 +23833,68 @@ With the @samp{*} parameter, if a variable object is bound to a
currently running thread, it will not be updated, without any
diagnostic.
+If @code{-var-set-update-range} was previously used on a varobj, then
+only the selected range of children will be reported.
+
+@code{-var-update} reports all the changed varobjs in a tuple named
+@samp{changelist}.
+
+Each item in the change list is itself a tuple holding:
+
+@table @samp
+@item name
+The name of the varobj.
+
+@item value
+If values were requested for this update, then this field will be
+present and will hold the value of the varobj.
+
+@item in_scope
+This is a string, either @samp{false} if the varobj is not in scope,
+or @samp{true} if it is in scope.
+
+@item type_changed
+This is only present if the varobj is still valid. If the type
+changed, then this will be the string @samp{true}; otherwise it will
+be @samp{false}.
+
+@item new_type
+If the varobj's type changed, then this field will be present and will
+hold the new type.
+
+@item new_num_children
+For a dynamic varobj, if the number of children changed, or if the
+type changed, this will be the new number of children.
+
+The @samp{numchild} field in other varobj responses is generally not
+valid for a dynamic varobj -- it will show the number of children that
+@value{GDBN} knows about, but because dynamic varobjs lazily
+instantiate their children, this will not reflect the number of
+children which may be available.
+
+The @samp{new_num_children} attribute only reports changes to the
+number of children known by @value{GDBN}. This is the only way to
+detect whether an update has removed children (which necessarily can
+only happen at the end of the update range).
+
+@item displayhint
+The display hint, if any.
+
+@item has_more
+This is an integer value, which will be 1 if there are more children
+available outside the varobj's update range.
+
+@item dynamic
+This attribute will be present and have the value @samp{1} if the
+varobj is a dynamic varobj. If the varobj is not a dynamic varobj,
+then this attribute will not be present.
+
+@item new_children
+If new children were added to a dynamic varobj within the selected
+update range (as set by @code{-var-set-update-range}), then they will
+be listed in this attribute.
+@end table
+
@subsubheading Example
@smallexample
@@ -23798,6 +23962,32 @@ Unfreezing a variable does not update it, only subsequent
(gdb)
@end smallexample
+@subheading The @code{-var-set-update-range} command
+@findex -var-set-update-range
+@anchor{-var-set-update-range}
+
+@subsubheading Synopsis
+
+@smallexample
+ -var-set-update-range @var{name} @var{from} @var{to}
+@end smallexample
+
+Set the range of children to be returned by future invocations of
+@code{-var-update}.
+
+@var{from} and @var{to} indicate the range of children to report. If
+@var{from} or @var{to} is less than zero, the range is reset and all
+children will be reported. Otherwise, children starting at @var{from}
+(zero-based) and ending just before @var{to} will be reported.
+
+@subsubheading Example
+
+@smallexample
+(gdb)
+-var-set-update-range V 1 2
+^done
+@end smallexample
+
@subheading The @code{-var-set-visualizer} command
@findex -var-set-visualizer
@anchor{-var-set-visualizer}
diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c
index 0cf03d9..ede928c 100644
--- a/gdb/mi/mi-cmd-var.c
+++ b/gdb/mi/mi-cmd-var.c
@@ -41,7 +41,7 @@ static void varobj_update_one (struct varobj *var,
enum print_values print_values,
int explicit);
-static int mi_print_value_p (struct type *type, enum print_values print_values);
+static int mi_print_value_p (struct varobj *var, enum print_values print_values);
/* Print variable object VAR. The PRINT_VALUES parameter controls
if the value should be printed. The PRINT_EXPRESSION parameter
@@ -59,8 +59,12 @@ print_varobj (struct varobj *var, enum print_values print_values,
ui_out_field_string (uiout, "exp", varobj_get_expression (var));
ui_out_field_int (uiout, "numchild", varobj_get_num_children (var));
- if (mi_print_value_p (varobj_get_gdb_type (var), print_values))
- ui_out_field_string (uiout, "value", varobj_get_value (var));
+ if (mi_print_value_p (var, print_values))
+ {
+ char *val = varobj_get_value (var);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
+ }
type = varobj_get_type (var);
if (type != NULL)
@@ -75,6 +79,9 @@ print_varobj (struct varobj *var, enum print_values print_values,
if (varobj_get_frozen (var))
ui_out_field_int (uiout, "frozen", 1);
+
+ if (varobj_pretty_printed_p (var))
+ ui_out_field_int (uiout, "dynamic", 1);
}
/* VAROBJ operations */
@@ -138,6 +145,8 @@ mi_cmd_var_create (char *command, char **argv, int argc)
print_varobj (var, PRINT_ALL_VALUES, 0 /* don't print expression */);
+ ui_out_field_int (uiout, "has_more", varobj_has_more (var, 0));
+
do_cleanups (old_cleanups);
}
@@ -223,6 +232,7 @@ mi_cmd_var_set_format (char *command, char **argv, int argc)
{
enum varobj_display_formats format;
struct varobj *var;
+ char *val;
if (argc != 2)
error (_("mi_cmd_var_set_format: Usage: NAME FORMAT."));
@@ -239,7 +249,9 @@ mi_cmd_var_set_format (char *command, char **argv, int argc)
ui_out_field_string (uiout, "format", varobj_format_string[(int) format]);
/* Report the value in the new format */
- ui_out_field_string (uiout, "value", varobj_get_value (var));
+ val = varobj_get_value (var);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
}
void
@@ -337,11 +349,12 @@ Must be: 0 or \"%s\", 1 or \"%s\", 2 or \"%s\""),
}
/* Return 1 if given the argument PRINT_VALUES we should display
- a value of type TYPE. */
+ the varobj VAR. */
static int
-mi_print_value_p (struct type *type, enum print_values print_values)
+mi_print_value_p (struct varobj *var, enum print_values print_values)
{
+ struct type *type;
if (print_values == PRINT_NO_VALUES)
return 0;
@@ -349,6 +362,10 @@ mi_print_value_p (struct type *type, enum print_values print_values)
if (print_values == PRINT_ALL_VALUES)
return 1;
+ if (varobj_pretty_printed_p (var))
+ return 1;
+
+ type = varobj_get_gdb_type (var);
if (type == NULL)
return 1;
else
@@ -369,24 +386,35 @@ mi_cmd_var_list_children (char *command, char **argv, int argc)
struct varobj *var;
VEC(varobj_p) *children;
struct varobj *child;
- struct cleanup *cleanup_children;
int numchild;
enum print_values print_values;
int ix;
+ int from, to;
char *display_hint;
- if (argc != 1 && argc != 2)
- error (_("mi_cmd_var_list_children: Usage: [PRINT_VALUES] NAME"));
+ if (argc < 1 || argc > 4)
+ error (_("mi_cmd_var_list_children: Usage: [PRINT_VALUES] NAME [FROM TO]"));
/* Get varobj handle, if a valid var obj name was specified */
- if (argc == 1)
+ if (argc == 1 || argc == 3)
var = varobj_get_handle (argv[0]);
else
var = varobj_get_handle (argv[1]);
- children = varobj_list_children (var);
- ui_out_field_int (uiout, "numchild", VEC_length (varobj_p, children));
- if (argc == 2)
+ if (argc > 2)
+ {
+ from = atoi (argv[argc - 2]);
+ to = atoi (argv[argc - 1]);
+ }
+ else
+ {
+ from = -1;
+ to = -1;
+ }
+
+ children = varobj_list_children (var, &from, &to);
+ ui_out_field_int (uiout, "numchild", to - from);
+ if (argc == 2 || argc == 4)
print_values = mi_parse_values_option (argv[0]);
else
print_values = PRINT_NO_VALUES;
@@ -398,21 +426,28 @@ mi_cmd_var_list_children (char *command, char **argv, int argc)
xfree (display_hint);
}
- if (VEC_length (varobj_p, children) == 0)
- return;
-
- if (mi_version (uiout) == 1)
- cleanup_children = make_cleanup_ui_out_tuple_begin_end (uiout, "children");
- else
- cleanup_children = make_cleanup_ui_out_list_begin_end (uiout, "children");
- for (ix = 0; VEC_iterate (varobj_p, children, ix, child); ++ix)
+ if (from < to)
{
- struct cleanup *cleanup_child;
- cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, "child");
- print_varobj (child, print_values, 1 /* print expression */);
- do_cleanups (cleanup_child);
+ struct cleanup *cleanup_children;
+ if (mi_version (uiout) == 1)
+ cleanup_children
+ = make_cleanup_ui_out_tuple_begin_end (uiout, "children");
+ else
+ cleanup_children
+ = make_cleanup_ui_out_list_begin_end (uiout, "children");
+ for (ix = from;
+ ix < to && VEC_iterate (varobj_p, children, ix, child);
+ ++ix)
+ {
+ struct cleanup *cleanup_child;
+ cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, "child");
+ print_varobj (child, print_values, 1 /* print expression */);
+ do_cleanups (cleanup_child);
+ }
+ do_cleanups (cleanup_children);
}
- do_cleanups (cleanup_children);
+
+ ui_out_field_int (uiout, "has_more", varobj_has_more (var, to));
}
void
@@ -538,16 +573,24 @@ mi_cmd_var_evaluate_expression (char *command, char **argv, int argc)
var = varobj_get_handle (argv[optind]);
if (formatFound)
- ui_out_field_string (uiout, "value", varobj_get_formatted_value (var, format));
+ {
+ char *val = varobj_get_formatted_value (var, format);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
+ }
else
- ui_out_field_string (uiout, "value", varobj_get_value (var));
+ {
+ char *val = varobj_get_value (var);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
+ }
}
void
mi_cmd_var_assign (char *command, char **argv, int argc)
{
struct varobj *var;
- char *expression;
+ char *expression, *val;
if (argc != 2)
error (_("mi_cmd_var_assign: Usage: NAME EXPRESSION."));
@@ -563,7 +606,9 @@ mi_cmd_var_assign (char *command, char **argv, int argc)
if (!varobj_set_value (var, expression))
error (_("mi_cmd_var_assign: Could not assign expression to variable object"));
- ui_out_field_string (uiout, "value", varobj_get_value (var));
+ val = varobj_get_value (var);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
}
/* Type used for parameters passing to mi_cmd_var_update_iter. */
@@ -670,6 +715,7 @@ varobj_update_one (struct varobj *var, enum print_values print_values,
for (i = 0; VEC_iterate (varobj_update_result, changes, i, r); ++i)
{
char *display_hint;
+ int from, to;
if (mi_version (uiout) > 1)
cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
@@ -678,8 +724,12 @@ varobj_update_one (struct varobj *var, enum print_values print_values,
switch (r->status)
{
case VAROBJ_IN_SCOPE:
- if (mi_print_value_p (varobj_get_gdb_type (r->varobj), print_values))
- ui_out_field_string (uiout, "value", varobj_get_value (r->varobj));
+ if (mi_print_value_p (r->varobj, print_values))
+ {
+ char *val = varobj_get_value (r->varobj);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
+ }
ui_out_field_string (uiout, "in_scope", "true");
break;
case VAROBJ_NOT_IN_SCOPE:
@@ -699,11 +749,11 @@ varobj_update_one (struct varobj *var, enum print_values print_values,
}
if (r->type_changed)
- {
- ui_out_field_string (uiout, "new_type", varobj_get_type (r->varobj));
- ui_out_field_int (uiout, "new_num_children",
- varobj_get_num_children (r->varobj));
- }
+ ui_out_field_string (uiout, "new_type", varobj_get_type (r->varobj));
+
+ if (r->type_changed || r->children_changed)
+ ui_out_field_int (uiout, "new_num_children",
+ varobj_get_num_children (r->varobj));
display_hint = varobj_get_display_hint (var);
if (display_hint)
@@ -712,28 +762,59 @@ varobj_update_one (struct varobj *var, enum print_values print_values,
xfree (display_hint);
}
- if (r->children_changed)
- {
- int ix;
- struct varobj *child;
- struct cleanup *cleanup =
- make_cleanup_ui_out_list_begin_end (uiout, "children");
+ if (varobj_pretty_printed_p (var))
+ ui_out_field_int (uiout, "dynamic", 1);
- VEC (varobj_p)* children = varobj_list_children (r->varobj);
+ varobj_get_child_range (r->varobj, &from, &to);
+ ui_out_field_int (uiout, "has_more",
+ varobj_has_more (r->varobj, to));
- for (ix = 0; VEC_iterate (varobj_p, children, ix, child); ++ix)
+ if (r->new)
+ {
+ int j;
+ varobj_p child;
+ struct cleanup *cleanup;
+
+ cleanup = make_cleanup_ui_out_list_begin_end (uiout, "new_children");
+ for (j = 0; VEC_iterate (varobj_p, r->new, j, child); ++j)
{
struct cleanup *cleanup_child;
cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
- print_varobj (child, print_values, 1 /* print expression */);
+ print_varobj (child, print_values, 1 /* print_expression */);
do_cleanups (cleanup_child);
}
do_cleanups (cleanup);
+ VEC_free (varobj_p, r->new);
+ r->new = NULL; /* Paranoia. */
}
-
+
if (mi_version (uiout) > 1)
do_cleanups (cleanup);
}
VEC_free (varobj_update_result, changes);
}
+
+void
+mi_cmd_enable_pretty_printing (char *command, char **argv, int argc)
+{
+ if (argc != 0)
+ error (_("mi_cmd_enable_pretty_printing: no arguments allowed"));
+ varobj_enable_pretty_printing ();
+}
+
+void
+mi_cmd_var_set_update_range (char *command, char **argv, int argc)
+{
+ struct varobj *var;
+ int from, to;
+
+ if (argc != 3)
+ error (_("mi_cmd_var_set_update_range: Usage: VAROBJ FROM TO"));
+
+ var = varobj_get_handle (argv[0]);
+ from = atoi (argv[1]);
+ to = atoi (argv[2]);
+
+ varobj_set_child_range (var, from, to);
+}
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index dd3d803..8ba086c 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -52,6 +52,7 @@ struct mi_cmd mi_cmds[] =
{ "data-write-memory", { NULL, 0 }, mi_cmd_data_write_memory},
{ "data-write-register-values", { NULL, 0 }, mi_cmd_data_write_register_values},
{ "enable-timings", { NULL, 0 }, mi_cmd_enable_timings},
+ { "enable-pretty-printing", { NULL, 0 }, mi_cmd_enable_pretty_printing},
{ "environment-cd", { NULL, 0 }, mi_cmd_env_cd},
{ "environment-directory", { NULL, 0 }, mi_cmd_env_dir},
{ "environment-path", { NULL, 0 }, mi_cmd_env_path},
@@ -112,6 +113,7 @@ struct mi_cmd mi_cmds[] =
{ "var-list-children", { NULL, 0 }, mi_cmd_var_list_children},
{ "var-set-format", { NULL, 0 }, mi_cmd_var_set_format},
{ "var-set-frozen", { NULL, 0 }, mi_cmd_var_set_frozen},
+ { "var-set-update-range", { NULL, 0 }, mi_cmd_var_set_update_range },
{ "var-set-visualizer", { NULL, 0 }, mi_cmd_var_set_visualizer},
{ "var-show-attributes", { NULL, 0 }, mi_cmd_var_show_attributes},
{ "var-show-format", { NULL, 0 }, mi_cmd_var_show_format},
diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h
index 85ad0c4..dfab411 100644
--- a/gdb/mi/mi-cmds.h
+++ b/gdb/mi/mi-cmds.h
@@ -99,6 +99,8 @@ extern mi_cmd_argv_ftype mi_cmd_var_set_visualizer;
extern mi_cmd_argv_ftype mi_cmd_var_show_attributes;
extern mi_cmd_argv_ftype mi_cmd_var_show_format;
extern mi_cmd_argv_ftype mi_cmd_var_update;
+extern mi_cmd_argv_ftype mi_cmd_enable_pretty_printing;
+extern mi_cmd_argv_ftype mi_cmd_var_set_update_range;
/* Description of a single command. */
diff --git a/gdb/testsuite/gdb.mi/gdb701.exp b/gdb/testsuite/gdb.mi/gdb701.exp
index d4acdc2..244c731 100644
--- a/gdb/testsuite/gdb.mi/gdb701.exp
+++ b/gdb/testsuite/gdb.mi/gdb701.exp
@@ -54,7 +54,7 @@ mi_gdb_test "-var-list-children fooPtr" \
foreach i [list x y z] {
mi_gdb_test "-var-list-children fooPtr.$i" \
- "(&\".*\"\r\n)*\\^done,numchild=\"0\"" \
+ "(&\".*\"\r\n)*\\^done,numchild=\"0\",has_more=\"0\"" \
"list children of fooPtr.$i"
}
diff --git a/gdb/testsuite/gdb.mi/mi-break.exp b/gdb/testsuite/gdb.mi/mi-break.exp
index 619727d..8d06c0e 100644
--- a/gdb/testsuite/gdb.mi/mi-break.exp
+++ b/gdb/testsuite/gdb.mi/mi-break.exp
@@ -175,7 +175,7 @@ proc test_error {} {
# containing function call, the internal breakpoint created to handle
# function call would be reported, messing up MI output.
mi_gdb_test "-var-create V * return_1()" \
- "\\^done,name=\"V\",numchild=\"0\",value=\"1\",type=\"int\"" \
+ "\\^done,name=\"V\",numchild=\"0\",value=\"1\",type=\"int\",has_more=\"0\"" \
"create varobj for function call"
mi_gdb_test "-var-update *" \
diff --git a/gdb/testsuite/gdb.mi/mi-var-block.exp b/gdb/testsuite/gdb.mi/mi-var-block.exp
index 8806848..93ded26 100644
--- a/gdb/testsuite/gdb.mi/mi-var-block.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-block.exp
@@ -74,7 +74,7 @@ mi_step_to "do_block_tests" "" "var-cmd.c" \
# Test: c_variable-3.4
# Desc: check foo, cb changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"foo\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"cb\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"foo\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"cb\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: cb foo changed"
# step to "foo = 321;"
diff --git a/gdb/testsuite/gdb.mi/mi-var-child.exp b/gdb/testsuite/gdb.mi/mi-var-child.exp
index 1f4bdc6..eb6c456 100644
--- a/gdb/testsuite/gdb.mi/mi-var-child.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-child.exp
@@ -680,7 +680,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.2
# Desc: check that integer changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.integer\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.integer"
# Step over:
@@ -693,7 +693,7 @@ mi_execute_to "exec-step 3" "end-stepping-range" do_children_tests {} ".*${srcfi
# Test: c_variable-5.3
# Desc: check that char_ptr changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.char_ptr"
# Step over "struct_declarations.int_ptr_ptr = &foo;"
@@ -703,7 +703,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.4
# Desc: check that int_ptr_ptr and children changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars int_ptr_ptr and children changed"
# Step over "weird->long_array[0] = 1234;"
@@ -713,7 +713,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.5
# Desc: check that long_array[0] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.0\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.0\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.0 changed"
# Step over "struct_declarations.long_array[1] = 2345;"
@@ -723,7 +723,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.6
# Desc: check that long_array[1] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.1\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.1\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.1 changed"
# Step over "weird->long_array[2] = 3456;"
@@ -733,7 +733,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.7
# Desc: check that long_array[2] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.2\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.2\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.2 changed"
# Step over:
@@ -752,7 +752,7 @@ mi_execute_to "exec-step 7" "end-stepping-range" do_children_tests {} ".*${srcfi
# Test: c_variable-5.8
# Desc: check that long_array[3-9] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.3\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.4\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.5\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.6\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.7\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.8\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.9\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.3\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.4\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.5\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.6\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.7\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.8\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.9\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.3-9 changed"
@@ -763,7 +763,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.9
# Desc: check that func_ptr changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.func_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.func_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.func_ptr changed"
# Step over "struct_declarations.long_array[10] = 3456";
@@ -771,7 +771,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
[expr $line_dct_nothing + 2] "step \$line_dct_nothing + 2"
mi_gdb_test "-var-update --no-values *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.10\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.10\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.10 changed, don't print values."
# Step over "struct_declarations.long_array[11] = 5678";
@@ -780,7 +780,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
$line_dct_a0_0 "step \$line_dct_a0_0"
mi_gdb_test "-var-update --all-values *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.11\",value=\"5678\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.11\",value=\"5678\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.11 changed, print values."
mi_list_varobj_children {struct_declarations.long_array --all-values} {
@@ -1121,7 +1121,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.47
# Desc: check that psnp->char_ptr (and [0].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr.\\*\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr.\\*\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->char_ptr (and 0.char_ptr) changed"
# Step over "snp1.char_ptr = &c3;"
@@ -1131,7 +1131,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.48
# Desc: check that psnp->next->char_ptr (and [1].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr.\\*\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr.\\*\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->char_ptr (and 1.char_ptr) changed"
@@ -1142,7 +1142,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.49
# Desc: check that psnp->next->next->char_ptr (and [2].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->next->char_ptr (and 2.char_ptr) changed"
@@ -1153,7 +1153,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.50
# Desc: check that psnp->long_ptr (and [0].long_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->long_ptr (and 0.long_ptr) changed"
@@ -1181,7 +1181,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.52
# Desc: check that psnp->next->next->long_ptr (and [2].long_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.long_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->next->long_ptr (and 2.long_ptr) changed"
mi_prepare_inline_tests $srcfile
diff --git a/gdb/testsuite/gdb.mi/mi-var-cmd.exp b/gdb/testsuite/gdb.mi/mi-var-cmd.exp
index ad2e55c..6efb333 100644
--- a/gdb/testsuite/gdb.mi/mi-var-cmd.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-cmd.exp
@@ -146,7 +146,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" $line_dlt_linteger "step at do_local
# Test: c_variable-2.2
# Desc: check whether only linteger changed values
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: linteger changed"
# Step over "lpinteger = &linteger;"
@@ -155,7 +155,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 1] "step
# Test: c_variable-2.3
# Desc: check whether only lpinteger changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpinteger changed"
# Step over "lcharacter = 'a';"
@@ -164,7 +164,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 2] "step
# Test: c_variable-2.4
# Desc: check whether only lcharacter changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lcharacter changed"
# Step over "lpcharacter = &lcharacter;"
@@ -173,7 +173,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 3] "step
# Test: c_variable-2.5
# Desc: check whether only lpcharacter changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpcharacter changed"
@@ -195,7 +195,7 @@ mi_execute_to "exec-step 9" "end-stepping-range" "do_locals_tests" "" \
# Desc: check whether llong, lplong, lfloat, lpfloat, ldouble, lpdouble, lsimple.integer,
# lsimple.unsigned_character lsimple.integer lsimple.character changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpdouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lplong\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpdouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lplong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: many changed"
# Step over:
@@ -212,7 +212,7 @@ mi_execute_to "exec-step 4" "end-stepping-range" "do_locals_tests" "" \
# Test: c_variable-2.7
# Desc: check whether (lsimple.signed_character, lsimple.char_ptr) lpsimple, func changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"func\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpsimple\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"func\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpsimple\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: func and lpsimple changed"
# Step over
@@ -234,7 +234,7 @@ mi_execute_to "exec-step 8" "end-stepping-range" "do_locals_tests" "" \
# Note: this test also checks that lpsimple->integer and lsimple.integer have
# changed (they are the same)
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lsimple and others changed"
@@ -257,7 +257,7 @@ mi_gdb_test "-var-assign linteger 3333" \
# change.
set lpchar_update "\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\},"
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[($lpchar_update)?\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[($lpchar_update)?\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: linteger changed after assign"
mi_gdb_test "-var-assign linteger 3333" \
@@ -277,7 +277,7 @@ mi_gdb_test "-var-assign lpinteger \"&linteger + 3\"" \
"assign to lpinteger"
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpinteger changed after assign"
mi_gdb_test "-var-update *" \
@@ -377,7 +377,7 @@ mi_gdb_test "-var-update *" \
"assign same value to func (update)"
mi_gdb_test "-var-create array_ptr * array_ptr" \
- "\\^done,name=\"array_ptr\",numchild=\"1\",value=\"$hex\",type=\"int \\*\"" \
+ "\\^done,name=\"array_ptr\",numchild=\"1\",value=\"$hex\",type=\"int \\*\",has_more=\"0\"" \
"create global variable array_ptr"
mi_gdb_test "-var-assign array_ptr array2" \
@@ -385,7 +385,7 @@ mi_gdb_test "-var-assign array_ptr array2" \
"assign array to pointer"
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"array_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"array_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"assign array to pointer (update)"
mi_gdb_test "-var-assign array_ptr array2" \
@@ -439,7 +439,7 @@ mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\
# Test: c_variable-2.13
# Desc: change subroutine1 local i
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"i\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"i\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: i changed"
mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\}" \
@@ -448,7 +448,7 @@ mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\
# Test: c_variable-2.14
# Desc: change do_locals_tests local llong
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: llong changed"
set line_dlt_call_subroutine1 [gdb_get_line_number "subroutine1 (linteger, &llong);"]
@@ -458,7 +458,7 @@ mi_next_to "do_locals_tests" "" "var-cmd.c" \
# Test: c_variable-2.15
# Desc: check for out of scope subroutine1 locals
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\,type_changed=\"false\"},\{name=\"i\",in_scope=\"false\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\,type_changed=\"false\",has_more=\"0\"},\{name=\"i\",in_scope=\"false\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: all now out of scope"
# Done with locals/globals tests. Erase all variables
@@ -550,14 +550,14 @@ mi_gdb_test "-var-create selected_a @ a" \
mi_continue_to incr_a
mi_gdb_test "-var-update selected_a" \
- "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"char\",new_num_children=\"0\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"char\",new_num_children=\"0\",has_more=\"0\"\}\\\]" \
"update selected_a in incr_a"
mi_next "step a line in incr_a"
mi_next "return from incr_a to do_special_tests"
mi_gdb_test "-var-update selected_a" \
- "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"int\",new_num_children=\"0\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"int\",new_num_children=\"0\",has_more=\"0\"\}\\\]" \
"update selected_a in do_special_tests"
mi_gdb_test "-file-exec-and-symbols ${binfile}" "\\^done" \
@@ -596,7 +596,7 @@ mi_check_varobj_value F 7 "check F inside callee"
# A varobj we fail to read during -var-update should be considered
# out of scope.
mi_gdb_test "-var-create null_ptr * **0" \
- {\^done,name="null_ptr",numchild="0",value=".*",type="int"} \
+ {\^done,name="null_ptr",numchild="0",value=".*",type="int",has_more="0"} \
"create null_ptr"
# Allow this to succeed, if address zero is readable, although it
@@ -644,7 +644,7 @@ mi_check_varobj_value "L" "{...}" "in-and-out-of-scope: check initial value"
mi_runto main
mi_gdb_test "-var-update L" \
- {\^done,changelist=\[{name="L",in_scope="false",type_changed="false"}\]} \
+ {\^done,changelist=\[{name="L",in_scope="false",type_changed="false",has_more="0"}\]} \
"in-and-out-of-scope: out of scope now"
mi_gdb_test "-var-update L" \
@@ -654,7 +654,7 @@ mi_gdb_test "-var-update L" \
mi_continue_to do_locals_tests
mi_gdb_test "-var-update L" \
- {\^done,changelist=\[{name="L",in_scope="true",type_changed="false"}\]} \
+ {\^done,changelist=\[{name="L",in_scope="true",type_changed="false",has_more="0"}\]} \
"in-and-out-of-scope: in scope now"
mi_gdb_test "-var-update L" \
diff --git a/gdb/testsuite/gdb.mi/mi-var-display.exp b/gdb/testsuite/gdb.mi/mi-var-display.exp
index 4b02e50..faa9172 100644
--- a/gdb/testsuite/gdb.mi/mi-var-display.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-display.exp
@@ -558,7 +558,7 @@ mi_gdb_test "-var-info-num-children e" \
# Test: c_variable-7.55
# Desc: children of e
mi_gdb_test "-var-list-children e" \
- "\\^done,numchild=\"0\"" \
+ "\\^done,numchild=\"0\",has_more=\"0\"" \
"get children of e"
# Test: c_variable-7.60
@@ -600,7 +600,7 @@ mi_gdb_test "-var-info-num-children anone" \
# Test: c_variable-7.75
# Desc: children of anone
mi_gdb_test "-var-list-children anone" \
- "\\^done,numchild=\"0\"" \
+ "\\^done,numchild=\"0\",has_more=\"0\"" \
"get children of anone"
diff --git a/gdb/testsuite/gdb.mi/mi-var-invalidate.exp b/gdb/testsuite/gdb.mi/mi-var-invalidate.exp
index 05d46fa..4b95674 100644
--- a/gdb/testsuite/gdb.mi/mi-var-invalidate.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-invalidate.exp
@@ -72,7 +72,7 @@ mi_runto main
# Check local variable is "invalid".
mi_gdb_test "-var-update linteger" \
- "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"invalid\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"invalid\",has_more=\"0\"\}\\\]" \
"linteger not anymore in scope due to binary changes"
mi_gdb_test "-var-info-type linteger" \
@@ -97,7 +97,7 @@ mi_delete_breakpoints
mi_gdb_load ${binfile2}
# Check local variable are "invalid"
mi_gdb_test "-var-update linteger" \
- "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"invalid\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"invalid\",has_more=\"0\"\}\\\]" \
"linteger not valid anymore due to binary changes"
mi_gdb_test "-var-info-type linteger" \
@@ -106,7 +106,7 @@ mi_gdb_test "-var-info-type linteger" \
# Check global variable are still correct.
mi_gdb_test "-var-update global_simple" \
- "\\^done,changelist=\\\[\{name=\"global_simple\",in_scope=\"invalid\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"global_simple\",in_scope=\"invalid\",has_more=\"0\"\}\\\]" \
"global_simple not anymore in scope due to binary changes"
mi_gdb_test "-var-info-type global_simple" \
diff --git a/gdb/testsuite/gdb.mi/mi2-var-block.exp b/gdb/testsuite/gdb.mi/mi2-var-block.exp
index 6bcfea3..9b3d08f 100644
--- a/gdb/testsuite/gdb.mi/mi2-var-block.exp
+++ b/gdb/testsuite/gdb.mi/mi2-var-block.exp
@@ -74,7 +74,7 @@ mi_step_to "do_block_tests" "" "var-cmd.c" \
# Test: c_variable-3.4
# Desc: check foo, cb changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"foo\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"cb\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"foo\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"cb\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: cb foo changed"
# step to "foo = 321;"
diff --git a/gdb/testsuite/gdb.mi/mi2-var-child.exp b/gdb/testsuite/gdb.mi/mi2-var-child.exp
index 161b34f..0f9b4d4 100644
--- a/gdb/testsuite/gdb.mi/mi2-var-child.exp
+++ b/gdb/testsuite/gdb.mi/mi2-var-child.exp
@@ -1,4 +1,4 @@
-# Copyright 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
+# Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2009 Free Software Foundation
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -680,7 +680,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.2
# Desc: check that integer changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.integer\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.integer"
# Step over:
@@ -693,7 +693,7 @@ mi_execute_to "exec-step 3" "end-stepping-range" do_children_tests {} {.*var-cmd
# Test: c_variable-5.3
# Desc: check that char_ptr changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.char_ptr"
# Step over "struct_declarations.int_ptr_ptr = &foo;"
@@ -703,7 +703,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.4
# Desc: check that int_ptr_ptr and children changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars int_ptr_ptr and children changed"
# Step over "weird->long_array[0] = 1234;"
@@ -713,7 +713,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.5
# Desc: check that long_array[0] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.0\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.0\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.0 changed"
# Step over "struct_declarations.long_array[1] = 2345;"
@@ -723,7 +723,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.6
# Desc: check that long_array[1] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.1\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.1\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.1 changed"
# Step over "weird->long_array[2] = 3456;"
@@ -733,7 +733,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.7
# Desc: check that long_array[2] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.2\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.2\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.2 changed"
# Step over:
@@ -752,7 +752,7 @@ mi_execute_to "exec-step 7" "end-stepping-range" do_children_tests {} {.*var-cmd
# Test: c_variable-5.8
# Desc: check that long_array[3-9] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.3\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.4\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.5\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.6\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.7\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.8\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.9\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.3\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.4\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.5\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.6\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.7\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.8\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.9\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.3-9 changed"
@@ -764,7 +764,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.9
# Desc: check that func_ptr changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.func_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.func_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.func_ptr changed"
# Delete all variables
@@ -1075,7 +1075,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.47
# Desc: check that psnp->char_ptr (and [0].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr.\\*\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr.\\*\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->char_ptr (and 0.char_ptr) changed"
# Step over "snp1.char_ptr = &c3;"
@@ -1085,7 +1085,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.48
# Desc: check that psnp->next->char_ptr (and [1].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr.\\*\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr.\\*\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->char_ptr (and 1.char_ptr) changed"
@@ -1096,7 +1096,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.49
# Desc: check that psnp->next->next->char_ptr (and [2].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->next->char_ptr (and 2.char_ptr) changed"
@@ -1107,7 +1107,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.50
# Desc: check that psnp->long_ptr (and [0].long_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->long_ptr (and 0.long_ptr) changed"
@@ -1120,7 +1120,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Why does this have a FIXME?
setup_xfail *-*-*
mi_gdb_test "-var-update *" \
- "FIXME\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.long_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "FIXME\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->long_ptr (and 1.long_ptr) changed"
clear_xfail *-*-*
@@ -1135,7 +1135,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.52
# Desc: check that psnp->next->next->long_ptr (and [2].long_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.long_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->next->long_ptr (and 2.long_ptr) changed"
diff --git a/gdb/testsuite/gdb.mi/mi2-var-cmd.exp b/gdb/testsuite/gdb.mi/mi2-var-cmd.exp
index dda77bb..e900d14 100644
--- a/gdb/testsuite/gdb.mi/mi2-var-cmd.exp
+++ b/gdb/testsuite/gdb.mi/mi2-var-cmd.exp
@@ -126,11 +126,6 @@ mi_gdb_test "-var-create int * int" \
"&\"Attempt to use a type name as an expression.\\\\n\".*\\^error,msg=\"mi_cmd_var_create: unable to create variable object\"" \
"create int"
-# The number 0 must be an invalid frame address and linteger a local variable.
-mi_gdb_test "-var-create invalidframe 0 linteger" \
- "\\^error,msg=\"Failed to find the specified frame\"" \
- "create variable with invalid FRAME-ADDR"
-
##### #####
# #
@@ -151,7 +146,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" $line_dlt_linteger "step at do_local
# Test: c_variable-2.2
# Desc: check whether only linteger changed values
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: linteger changed"
# Step over "lpinteger = &linteger;"
@@ -160,7 +155,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 1] "step
# Test: c_variable-2.3
# Desc: check whether only lpinteger changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpinteger changed"
# Step over "lcharacter = 'a';"
@@ -169,7 +164,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 2] "step
# Test: c_variable-2.4
# Desc: check whether only lcharacter changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lcharacter changed"
# Step over "lpcharacter = &lcharacter;"
@@ -178,7 +173,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 3] "step
# Test: c_variable-2.5
# Desc: check whether only lpcharacter changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpcharacter changed"
@@ -200,7 +195,7 @@ mi_execute_to "exec-step 9" "end-stepping-range" "do_locals_tests" "" \
# Desc: check whether llong, lplong, lfloat, lpfloat, ldouble, lpdouble, lsimple.integer,
# lsimple.unsigned_character lsimple.integer lsimple.character changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpdouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lplong\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpdouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lplong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: many changed"
# Step over:
@@ -217,7 +212,7 @@ mi_execute_to "exec-step 4" "end-stepping-range" "do_locals_tests" "" \
# Test: c_variable-2.7
# Desc: check whether (lsimple.signed_character, lsimple.char_ptr) lpsimple, func changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"func\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpsimple\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"func\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpsimple\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: func and lpsimple changed"
# Step over
@@ -239,7 +234,7 @@ mi_execute_to "exec-step 8" "end-stepping-range" "do_locals_tests" "" \
# Note: this test also checks that lpsimple->integer and lsimple.integer have
# changed (they are the same)
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lsimple and others changed"
@@ -262,7 +257,7 @@ mi_gdb_test "-var-assign linteger 3333" \
# change.
set lpchar_update "\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\},"
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[($lpchar_update)?\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[($lpchar_update)?\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: linteger changed after assign"
mi_gdb_test "-var-assign linteger 3333" \
@@ -282,7 +277,7 @@ mi_gdb_test "-var-assign lpinteger \"&linteger + 3\"" \
"assign to lpinteger"
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpinteger changed after assign"
mi_gdb_test "-var-update *" \
@@ -407,7 +402,7 @@ mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\
# Test: c_variable-2.13
# Desc: change subroutine1 local i
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"i\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"i\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: i changed"
mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\}" \
@@ -416,7 +411,7 @@ mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\
# Test: c_variable-2.14
# Desc: change do_locals_tests local llong
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: llong changed"
set line_dlt_call_subroutine1 [gdb_get_line_number "subroutine1 (linteger, &llong);"]
@@ -426,7 +421,7 @@ mi_next_to "do_locals_tests" "" "var-cmd.c" \
# Test: c_variable-2.15
# Desc: check for out of scope subroutine1 locals
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\,type_changed=\"false\"},\{name=\"i\",in_scope=\"false\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\,type_changed=\"false\",has_more=\"0\"},\{name=\"i\",in_scope=\"false\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: all now out of scope"
# Done with locals/globals tests. Erase all variables
@@ -518,14 +513,14 @@ mi_gdb_test "-var-create selected_a @ a" \
mi_continue_to incr_a
mi_gdb_test "-var-update selected_a" \
- "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"char\",new_num_children=\"0\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"char\",new_num_children=\"0\"\,has_more=\"0\"}\\\]" \
"update selected_a in incr_a"
mi_next "step a line in incr_a"
mi_next "return from incr_a to do_special_tests"
mi_gdb_test "-var-update selected_a" \
- "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"int\",new_num_children=\"0\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"int\",new_num_children=\"0\",has_more=\"0\"\}\\\]" \
"update selected_a in do_special_tests"
mi_gdb_test "-file-exec-and-symbols ${binfile}" "\\^done" \
diff --git a/gdb/testsuite/gdb.mi/mi2-var-display.exp b/gdb/testsuite/gdb.mi/mi2-var-display.exp
index d6ce673..17e208a 100644
--- a/gdb/testsuite/gdb.mi/mi2-var-display.exp
+++ b/gdb/testsuite/gdb.mi/mi2-var-display.exp
@@ -557,7 +557,7 @@ mi_gdb_test "-var-info-num-children e" \
# Test: c_variable-7.55
# Desc: children of e
mi_gdb_test "-var-list-children e" \
- "\\^done,numchild=\"0\"" \
+ "\\^done,numchild=\"0\",has_more=\"0\"" \
"get children of e"
# Test: c_variable-7.60
@@ -599,7 +599,7 @@ mi_gdb_test "-var-info-num-children anone" \
# Test: c_variable-7.75
# Desc: children of anone
mi_gdb_test "-var-list-children anone" \
- "\\^done,numchild=\"0\"" \
+ "\\^done,numchild=\"0\",has_more=\"0\"" \
"get children of anone"
diff --git a/gdb/testsuite/gdb.python/python-mi.exp b/gdb/testsuite/gdb.python/python-mi.exp
index 3258810..bfdb595 100644
--- a/gdb/testsuite/gdb.python/python-mi.exp
+++ b/gdb/testsuite/gdb.python/python-mi.exp
@@ -48,23 +48,53 @@ mi_gdb_test "python execfile ('${srcdir}/${subdir}/${testfile}.py')" ""
mi_continue_to_line [gdb_get_line_number {MI breakpoint here} ${testfile}.c] \
"step to breakpoint"
-mi_create_floating_varobj container c "create container varobj"
+mi_create_dynamic_varobj container c \
+ "create container varobj, no pretty-printing"
+
+mi_list_varobj_children container {
+ { container.name name 1 string }
+ { container.len len 0 int }
+ { container.elements elements 1 "int ." }
+} "examine container children=0, no pretty-printing"
+
+mi_delete_varobj container "delete varobj"
+
+mi_gdb_test "-enable-pretty-printing" ""
+
+mi_create_varobj_checked string string_1 \
+ "struct string_repr" \
+ "create string_1 varobj"
+
+mi_gdb_test "-data-evaluate-expression \"string_1 = string_2\"" ".*" \
+ "assign string_1 from string_2"
+
+mi_gdb_test "-var-update string" \
+ "\\^done,changelist=\\\[{name=\"string\",in_scope=\"true\",type_changed=\"false\",dynamic=\"1\",has_more=\"0\"}\\\]" \
+ "update string varobj after assignment"
+
+mi_create_dynamic_varobj container c \
+ "create container varobj"
mi_list_varobj_children container {
} "examine container children=0"
mi_next "next over update 1"
-mi_varobj_update_dynamic container {
- { {container.\[0\]} {\[0\]} 0 int }
-} "varobj update 1"
+mi_varobj_update_dynamic container "varobj update 1" {
+ type_changed false new_num_children 1 dynamic 1 has_more 0
+} {
+} {
+ { name {container.\[0\]} exp {\[0\]} numchild 0 type int thread-id 1 }
+}
mi_next "next over update 2"
-mi_varobj_update_dynamic container {
- { {container.\[0\]} {\[0\]} 0 int }
- { {container.\[1\]} {\[1\]} 0 int }
-} "varobj update 2"
+mi_varobj_update_dynamic container "varobj update 2" {
+ type_changed false new_num_children 2 dynamic 1 has_more 0
+} {
+} {
+ { name {container.\[1\]} exp {\[1\]} numchild 0 type int thread-id 1 }
+}
mi_gdb_test "-var-set-visualizer container None" \
"\\^done" \
@@ -78,19 +108,111 @@ mi_gdb_test "-var-set-visualizer container gdb.default_visualizer" \
"\\^done" \
"choose default visualizer"
-mi_varobj_update_dynamic container {
- { {container.\[0\]} {\[0\]} 0 int }
- { {container.\[1\]} {\[1\]} 0 int }
-} "varobj update after choosing default"
+mi_varobj_update_dynamic container "varobj update after choosing default" {
+ type_changed false new_num_children 2 dynamic 1 has_more 0
+} {
+} {
+ { name {container.\[0\]} exp {\[0\]} numchild 0 type int thread-id 1 }
+ { name {container.\[1\]} exp {\[1\]} numchild 0 type int thread-id 1 }
+}
mi_gdb_test "-var-set-visualizer container ContainerPrinter" \
"\\^done" \
"choose visualizer using expression"
-mi_varobj_update_dynamic container {
+mi_varobj_update_dynamic container \
+ "varobj update after choosing via expression" {
+ type_changed false new_num_children 2 dynamic 1 has_more 0
+ } {
+ } {
+ { name {container.\[0\]} exp {\[0\]} numchild 0 type int thread-id 1 }
+ { name {container.\[1\]} exp {\[1\]} numchild 0 type int thread-id 1 }
+ }
+
+mi_list_varobj_children_range container 1 2 2 {
+ { {container.\[1\]} {\[1\]} 0 int }
+} "list varobj children after selecting child range"
+
+mi_list_varobj_children_range container -1 -1 2 {
+ { {container.\[0\]} {\[0\]} 0 int }
+ { {container.\[1\]} {\[1\]} 0 int }
+} "list varobj children after resetting child range"
+
+mi_next "next over update 3"
+
+mi_gdb_test "-var-set-update-range container 0 1" \
+ "\\^done" \
+ "set update range"
+
+# This should truncate the list.
+mi_list_varobj_children container {
{ {container.\[0\]} {\[0\]} 0 int }
+} "list children after setting update range"
+
+# This should return just the items in [1,2).
+mi_list_varobj_children_range container 1 2 2 {
{ {container.\[1\]} {\[1\]} 0 int }
-} "varobj update after choosing via expression"
+} "list selected children after setting range"
+
+# This should not be affected by the previous list-children request.
+mi_list_varobj_children container {
+ { {container.\[0\]} {\[0\]} 0 int }
+} "list children after listing selected range"
+
+mi_next "next over update 4"
+
+
+# Regression test: examine an object that has no children, then update
+# it to ensure that we don't print the children.
+mi_create_dynamic_varobj container2 c2 \
+ "create second container varobj"
+
+mi_gdb_test "-var-update container2" \
+ "\\^done,changelist=.." \
+ "update varobj, no children requested"
+
+mi_next "next over update 5"
+
+# Now container2 has an element -- and an update should mention that
+# it has_more. But, because we did not request children, we still
+# should not actually see them.
+mi_varobj_update_dynamic container2 \
+ "update varobj 2, no children requested" {
+ type_changed false dynamic 1 has_more 1
+ } {} {}
+
+# This should only show the first child, because the update range has
+# been set.
+mi_varobj_update_dynamic container \
+ "update after next with restricted range" {
+ type_changed false new_num_children 1 dynamic 1 has_more 1
+ } {
+ { name {container.\[0\]} in_scope true type_changed false dynamic 1 has_more 0 }
+ } {
+ }
+
+mi_continue_to_line \
+ [gdb_get_line_number {MI outer breakpoint here} ${testfile}.c] \
+ "step to outer breakpoint"
+
+mi_create_dynamic_varobj outer outer \
+ "create outer varobj"
+
+mi_list_varobj_children outer {
+ { outer.s s 2 "struct substruct" }
+ { outer.x x 0 "int" }
+} "list children of outer"
+
+mi_list_varobj_children outer.s {
+ { outer.s.a a 0 int }
+ { outer.s.b b 0 int }
+} "list children of outer.s"
+
+mi_next "next over outer update"
+
+mi_gdb_test "-var-update outer" \
+ ".done,changelist=.{name=\"outer.s.a\",in_scope=\"true\",type_changed=\"false\",dynamic=\"1\",has_more=\"0\"}." \
+ "update after updating element of outer"
mi_continue_to_line \
[gdb_get_line_number {Another MI breakpoint} ${testfile}.c] \
diff --git a/gdb/testsuite/gdb.python/python-prettyprint.c b/gdb/testsuite/gdb.python/python-prettyprint.c
index 3cafc48..bf41ebc 100644
--- a/gdb/testsuite/gdb.python/python-prettyprint.c
+++ b/gdb/testsuite/gdb.python/python-prettyprint.c
@@ -15,6 +15,8 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
+#include <string.h>
+
struct s
{
int a;
@@ -80,6 +82,29 @@ class Derived : public Vbase1, public Vbase2, public Vbase3
#endif
+struct substruct {
+ int a;
+ int b;
+};
+
+struct outerstruct {
+ struct substruct s;
+ int x;
+};
+
+struct outerstruct
+substruct_test (void)
+{
+ struct outerstruct outer;
+ outer.s.a = 0;
+ outer.s.b = 0;
+ outer.x = 0;
+
+ outer.s.a = 3; /* MI outer breakpoint here */
+
+ return outer;
+}
+
typedef struct string_repr
{
struct whybother
@@ -148,6 +173,14 @@ void do_nothing(void)
c = 23; /* Another MI breakpoint */
}
+struct nullstr
+{
+ char *s;
+};
+
+struct string_repr string_1 = { { "one" } };
+struct string_repr string_2 = { { "two" } };
+
int
main ()
{
@@ -155,11 +188,15 @@ main ()
struct ss ssa[2];
string x = make_string ("this is x");
zzz_type c = make_container ("container");
+ zzz_type c2 = make_container ("container2");
const struct string_repr cstring = { { "const string" } };
+ /* Clearing by being `static' could invoke an other GDB C++ bug. */
+ struct nullstr nullstr;
init_ss(&ss, 1, 2);
init_ss(ssa+0, 3, 4);
init_ss(ssa+1, 5, 6);
+ memset (&nullstr, 0, sizeof nullstr);
struct ns ns;
ns.null_str = "embedded\0null\0string";
@@ -193,6 +230,13 @@ main ()
add_item (&c, 72);
#ifdef MI
+ add_item (&c, 1011);
+ c.elements[0] = 1023;
+
+ add_item (&c2, 2222);
+ add_item (&c2, 3333);
+
+ substruct_test ();
do_nothing ();
#endif
diff --git a/gdb/testsuite/gdb.python/python-prettyprint.py b/gdb/testsuite/gdb.python/python-prettyprint.py
index bf009a1..2f070d8 100644
--- a/gdb/testsuite/gdb.python/python-prettyprint.py
+++ b/gdb/testsuite/gdb.python/python-prettyprint.py
@@ -92,6 +92,13 @@ class pp_vbase1:
def to_string (self):
return "pp class name: " + self.val.type.tag
+class pp_nullstr:
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ return self.val['s'].string(gdb.parameter('target-charset'))
+
class pp_ns:
"Print a std::basic_string of some kind"
@@ -105,11 +112,24 @@ class pp_ns:
def display_hint (self):
return 'string'
+class pp_outer:
+ "Print struct outer"
+
+ def __init__ (self, val):
+ self.val = val
+
+ def to_string (self):
+ return "x = %s" % self.val['x']
+
+ def children (self):
+ yield 's', self.val['s']
+ yield 'x', self.val['x']
+
def lookup_function (val):
"Look-up and return a pretty-printer that can print val."
# Get the type.
- type = val.type;
+ type = val.type
# If it points to a reference, get the reference.
if type.code == gdb.TYPE_CODE_REF:
@@ -148,6 +168,9 @@ def register_pretty_printers ():
pretty_printers_dict[re.compile ('^VirtualTest$')] = pp_multiple_virtual
pretty_printers_dict[re.compile ('^Vbase1$')] = pp_vbase1
+
+ pretty_printers_dict[re.compile ('^struct nullstr$')] = pp_nullstr
+ pretty_printers_dict[re.compile ('^nullstr$')] = pp_nullstr
# Note that we purposely omit the typedef names here.
# Printer lookup is based on canonical name.
@@ -160,6 +183,10 @@ def register_pretty_printers ():
pretty_printers_dict[re.compile ('^struct ns$')] = pp_ns
pretty_printers_dict[re.compile ('^ns$')] = pp_ns
+
+ pretty_printers_dict[re.compile ('^struct outerstruct$')] = pp_outer
+ pretty_printers_dict[re.compile ('^outerstruct$')] = pp_outer
+
pretty_printers_dict = {}
register_pretty_printers ()
diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
index e691232..167a02c 100644
--- a/gdb/testsuite/lib/mi-support.exp
+++ b/gdb/testsuite/lib/mi-support.exp
@@ -1195,13 +1195,13 @@ proc mi_list_breakpoints { expected test } {
# Name cannot be "-".
proc mi_create_varobj { name expression testname } {
mi_gdb_test "-var-create $name * $expression" \
- "\\^done,name=\"$name\",numchild=\"\[0-9\]+\",value=\".*\",type=.*" \
+ "\\^done,name=\"$name\",numchild=\"\[0-9\]+\",value=\".*\",type=.*,has_more=\"0\"" \
$testname
}
proc mi_create_floating_varobj { name expression testname } {
mi_gdb_test "-var-create $name @ $expression" \
- "\\^done,name=\"$name\",numchild=\"\[0-9\]+\",value=\".*\",type=.*" \
+ "\\^done,name=\"$name\",numchild=\"\(-1\|\[0-9\]+\)\",value=\".*\",type=.*" \
$testname
}
@@ -1214,6 +1214,14 @@ proc mi_create_varobj_checked { name expression type testname } {
$testname
}
+# Same as mi_create_floating_varobj, but assumes the test is creating
+# a dynamic varobj that has children, so the value must be "{...}".
+proc mi_create_dynamic_varobj {name expression testname} {
+ mi_gdb_test "-var-create $name @ $expression" \
+ "\\^done,name=\"$name\",numchild=\"\(-1\|\[0-9\]+\)\",value=\"{\\.\\.\\.}\",type=.*" \
+ $testname
+}
+
# Deletes the specified NAME.
proc mi_delete_varobj { name testname } {
mi_gdb_test "-var-delete $name" \
@@ -1229,7 +1237,7 @@ proc mi_varobj_update { name expected testname } {
set er "\\^done,changelist=\\\["
set first 1
foreach item $expected {
- set v "{name=\"$item\",in_scope=\"true\",type_changed=\"false\"}"
+ set v "{name=\"$item\",in_scope=\"true\",type_changed=\"false\",has_more=\".\"}"
if {$first == 1} {
set er "$er$v"
set first 0
@@ -1244,22 +1252,70 @@ proc mi_varobj_update { name expected testname } {
}
proc mi_varobj_update_with_type_change { name new_type new_children testname } {
- set v "{name=\"$name\",in_scope=\"true\",type_changed=\"true\",new_type=\"$new_type\",new_num_children=\"$new_children\"}"
+ set v "{name=\"$name\",in_scope=\"true\",type_changed=\"true\",new_type=\"$new_type\",new_num_children=\"$new_children\",has_more=\".\"}"
set er "\\^done,changelist=\\\[$v\\\]"
verbose -log "Expecting: $er"
mi_gdb_test "-var-update $name" $er $testname
}
-# Update a dynamic varobj named NAME. CHILDREN is a list of children,
-# in the same form as mi_list_varobj_children. TESTNAME is the name
-# of the test.
-proc mi_varobj_update_dynamic {name children testname} {
- set children_exp_j [mi_child_regexp $children 0]
+# A helper that turns a key/value list into a regular expression
+# matching some MI output.
+proc mi_varobj_update_kv_helper {list} {
+ set first 1
+ set rx ""
+ foreach {key value} $list {
+ if {!$first} {
+ append rx ,
+ }
+ set first 0
+ if {$key == "new_children"} {
+ append rx "$key=\\\[$value\\\]"
+ } else {
+ append rx "$key=\"$value\""
+ }
+ }
+ return $rx
+}
- set er "\\^done,changelist=\\\["
+# A helper for mi_varobj_update_dynamic that computes a match
+# expression given a child list.
+proc mi_varobj_update_dynamic_helper {children} {
+ set crx ""
- append er "{name=\"$name\",in_scope=\"true\",type_changed=\"false\""
- append er ",children=\\\[$children_exp_j.*\\\]}\\\]"
+ set first 1
+ foreach child $children {
+ if {!$first} {
+ append crx ,
+ }
+ set first 0
+ append crx "{"
+ append crx [mi_varobj_update_kv_helper $child]
+ append crx "}"
+ }
+
+ return $crx
+}
+
+# Update a dynamic varobj named NAME. CHILDREN is a list of children
+# that have been updated; NEW_CHILDREN is a list of children that were
+# added to the primary varobj. Each child is a list of key/value
+# pairs that are expected. SELF is a key/value list holding
+# information about the varobj itself. TESTNAME is the name of the
+# test.
+proc mi_varobj_update_dynamic {name testname self children new_children} {
+ if {[llength $new_children]} {
+ set newrx [mi_varobj_update_dynamic_helper $new_children]
+ lappend self new_children $newrx
+ }
+ set selfrx [mi_varobj_update_kv_helper $self]
+ set crx [mi_varobj_update_dynamic_helper $children]
+
+ set er "\\^done,changelist=\\\[\{name=\"$name\",in_scope=\"true\""
+ append er ",$selfrx\}"
+ if {"$crx" != ""} {
+ append er ",$crx"
+ }
+ append er "\\\]"
verbose -log "Expecting: $er"
mi_gdb_test "-var-update $name" $er $testname
@@ -1329,14 +1385,13 @@ proc mi_child_regexp {children add_child} {
# have no value.
#
proc mi_list_varobj_children { varname children testname } {
- mi_list_varobj_children_range $varname [llength $children] $children \
+ mi_list_varobj_children_range $varname "" "" [llength $children] $children \
$testname
}
-# Like mi_list_varobj_children, but assumes that a subrange has been
-# selected with -var-set-child-range. NUMCHILDREN is the total number
-# of children.
-proc mi_list_varobj_children_range {varname numchildren children testname} {
+# Like mi_list_varobj_children, but sets a subrange. NUMCHILDREN is
+# the total number of children.
+proc mi_list_varobj_children_range {varname from to numchildren children testname} {
set options ""
if {[llength $varname] == 2} {
set options [lindex $varname 1]
@@ -1352,9 +1407,18 @@ proc mi_list_varobj_children_range {varname numchildren children testname} {
set expected "\\^done,numchild=\"0\""
}
+ if {"$to" == ""} {
+ append expected ",has_more=\"0\""
+ } elseif {$to >= 0 && $numchildren > $to} {
+ append expected ",has_more=\"1\""
+ } else {
+ append expected ",has_more=\"0\""
+ }
+
verbose -log "Expecting: $expected"
- mi_gdb_test "-var-list-children $options $varname" $expected $testname
+ mi_gdb_test "-var-list-children $options $varname $from $to" \
+ $expected $testname
}
# Verifies that variable object VARNAME has NUMBER children,
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 603071f..e884e19 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -29,6 +29,7 @@
#include "gdb_assert.h"
#include "gdb_string.h"
+#include "gdb_regex.h"
#include "varobj.h"
#include "vec.h"
@@ -59,6 +60,15 @@ char *varobj_format_string[] =
/* String representations of gdb's known languages */
char *varobj_language_string[] = { "unknown", "C", "C++", "Java" };
+/* True if we want to allow Python-based pretty-printing. */
+static int pretty_printing = 0;
+
+void
+varobj_enable_pretty_printing (void)
+{
+ pretty_printing = 1;
+}
+
/* Data structures */
/* Every root variable has one of these structures saved in its
@@ -173,9 +183,31 @@ struct varobj
frozen. */
int not_fetched;
+ /* Sub-range of children which the MI consumer has requested. If
+ FROM < 0 or TO < 0, means that all children have been
+ requested. */
+ int from;
+ int to;
+
+ /* The pretty-printer constructor. If NULL, then the default
+ pretty-printer will be looked up. If None, then no
+ pretty-printer will be installed. */
+ PyObject *constructor;
+
/* The pretty-printer that has been constructed. If NULL, then a
new printer object is needed, and one will be constructed. */
PyObject *pretty_printer;
+
+ /* The iterator returned by the printer's 'children' method, or NULL
+ if not available. */
+ PyObject *child_iter;
+
+ /* We request one extra item from the iterator, so that we can
+ report to the caller whether there are more items than we have
+ already reported. However, we don't want to install this value
+ when we read it, because that will mess up future updates. So,
+ we stash it here instead. */
+ PyObject *saved_item;
};
struct cpstack
@@ -236,8 +268,6 @@ static char *cppop (struct cpstack **pstack);
static int install_new_value (struct varobj *var, struct value *value,
int initial);
-static void install_default_visualizer (struct varobj *var);
-
/* Language-specific routines. */
static enum varobj_languages variable_language (struct varobj *var);
@@ -623,7 +653,6 @@ varobj_create (char *objname,
}
}
- install_default_visualizer (var);
discard_cleanups (old_chain);
return var;
}
@@ -738,15 +767,8 @@ instantiate_pretty_printer (PyObject *constructor, struct value *value)
#if HAVE_PYTHON
PyObject *val_obj = NULL;
PyObject *printer;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- value = value_copy (value);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
val_obj = value_to_value_object (value);
-
if (! val_obj)
return NULL;
@@ -810,6 +832,17 @@ varobj_get_display_hint (struct varobj *var)
return result;
}
+/* Return true if the varobj has items after TO, false otherwise. */
+
+int
+varobj_has_more (struct varobj *var, int to)
+{
+ if (VEC_length (varobj_p, var->children) > to)
+ return 1;
+ return ((to == -1 || VEC_length (varobj_p, var->children) == to)
+ && var->saved_item != NULL);
+}
+
/* If the variable object is bound to a specific thread, that
is its evaluation can always be done in context of a frame
inside that thread, returns GDB id of the thread -- which
@@ -842,22 +875,94 @@ varobj_get_frozen (struct varobj *var)
return var->frozen;
}
+/* A helper function that restricts a range to what is actually
+ available in a VEC. This follows the usual rules for the meaning
+ of FROM and TO -- if either is negative, the entire range is
+ used. */
+
+static void
+restrict_range (VEC (varobj_p) *children, int *from, int *to)
+{
+ if (*from < 0 || *to < 0)
+ {
+ *from = 0;
+ *to = VEC_length (varobj_p, children);
+ }
+ else
+ {
+ if (*from > VEC_length (varobj_p, children))
+ *from = VEC_length (varobj_p, children);
+ if (*to > VEC_length (varobj_p, children))
+ *to = VEC_length (varobj_p, children);
+ if (*from > *to)
+ *from = *to;
+ }
+}
+
+/* A helper for update_dynamic_varobj_children that installs a new
+ child when needed. */
+
+static void
+install_dynamic_child (struct varobj *var,
+ VEC (varobj_p) **changed,
+ VEC (varobj_p) **new,
+ VEC (varobj_p) **unchanged,
+ int *cchanged,
+ int index,
+ const char *name,
+ struct value *value)
+{
+ if (VEC_length (varobj_p, var->children) < index + 1)
+ {
+ /* There's no child yet. */
+ struct varobj *child = varobj_add_child (var, name, value);
+ if (new)
+ VEC_safe_push (varobj_p, *new, child);
+ *cchanged = 1;
+ }
+ else
+ {
+ varobj_p existing = VEC_index (varobj_p, var->children, index);
+ if (install_new_value (existing, value, 0))
+ {
+ if (changed)
+ VEC_safe_push (varobj_p, *changed, existing);
+ }
+ else if (unchanged)
+ VEC_safe_push (varobj_p, *unchanged, existing);
+ }
+}
+
+#if HAVE_PYTHON
+
+static int
+dynamic_varobj_has_child_method (struct varobj *var)
+{
+ struct cleanup *back_to;
+ PyObject *printer = var->pretty_printer;
+ int result;
+
+ back_to = varobj_ensure_python_env (var);
+ result = PyObject_HasAttr (printer, gdbpy_children_cst);
+ do_cleanups (back_to);
+ return result;
+}
+
+#endif
+
static int
update_dynamic_varobj_children (struct varobj *var,
VEC (varobj_p) **changed,
- VEC (varobj_p) **new_and_unchanged,
- int *cchanged)
-
+ VEC (varobj_p) **new,
+ VEC (varobj_p) **unchanged,
+ int *cchanged,
+ int update_children,
+ int to)
{
#if HAVE_PYTHON
- /* FIXME: we *might* want to provide this functionality as
- a standalone function, so that other interested parties
- than varobj code can benefit for this. */
struct cleanup *back_to;
PyObject *children;
- PyObject *iterator;
int i;
- int children_changed = 0;
PyObject *printer = var->pretty_printer;
back_to = varobj_ensure_python_env (var);
@@ -869,87 +974,103 @@ update_dynamic_varobj_children (struct varobj *var,
return 0;
}
- children = PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
- NULL);
-
- if (!children)
+ if (update_children || !var->child_iter)
{
- gdbpy_print_stack ();
- error (_("Null value returned for children"));
- }
+ children = PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
+ NULL);
- make_cleanup_py_decref (children);
+ if (!children)
+ {
+ gdbpy_print_stack ();
+ error (_("Null value returned for children"));
+ }
- if (!PyIter_Check (children))
- error (_("Returned value is not iterable"));
+ make_cleanup_py_decref (children);
- iterator = PyObject_GetIter (children);
- if (!iterator)
- {
- gdbpy_print_stack ();
- error (_("Could not get children iterator"));
+ if (!PyIter_Check (children))
+ error (_("Returned value is not iterable"));
+
+ Py_XDECREF (var->child_iter);
+ var->child_iter = PyObject_GetIter (children);
+ if (!var->child_iter)
+ {
+ gdbpy_print_stack ();
+ error (_("Could not get children iterator"));
+ }
+
+ Py_XDECREF (var->saved_item);
+ var->saved_item = NULL;
+
+ i = 0;
}
- make_cleanup_py_decref (iterator);
+ else
+ i = VEC_length (varobj_p, var->children);
- for (i = 0; ; ++i)
+ /* We ask for one extra child, so that MI can report whether there
+ are more children. */
+ for (; to < 0 || i < to + 1; ++i)
{
- PyObject *item = PyIter_Next (iterator);
- PyObject *py_v;
- struct value *v;
- char *name;
- struct cleanup *inner;
-
+ PyObject *item;
+
+ /* See if there was a leftover from last time. */
+ if (var->saved_item)
+ {
+ item = var->saved_item;
+ var->saved_item = NULL;
+ }
+ else
+ item = PyIter_Next (var->child_iter);
+
if (!item)
break;
- inner = make_cleanup_py_decref (item);
- if (!PyArg_ParseTuple (item, "sO", &name, &py_v))
- error (_("Invalid item from the child list"));
-
- v = convert_value_from_python (py_v);
+ /* We don't want to push the extra child on any report list. */
+ if (to < 0 || i < to)
+ {
+ PyObject *py_v;
+ char *name;
+ struct value *v;
+ struct cleanup *inner;
- /* TODO: This assume the name of the i-th child never changes. */
+ inner = make_cleanup_py_decref (item);
- /* Now see what to do here. */
- if (VEC_length (varobj_p, var->children) < i + 1)
- {
- /* There's no child yet. */
- struct varobj *child = varobj_add_child (var, name, v);
- if (new_and_unchanged)
- VEC_safe_push (varobj_p, *new_and_unchanged, child);
- children_changed = 1;
+ if (!PyArg_ParseTuple (item, "sO", &name, &py_v))
+ error (_("Invalid item from the child list"));
+
+ v = convert_value_from_python (py_v);
+ install_dynamic_child (var, changed, new, unchanged,
+ cchanged, i, name, v);
+ do_cleanups (inner);
}
- else
+ else
{
- varobj_p existing = VEC_index (varobj_p, var->children, i);
- if (install_new_value (existing, v, 0) && changed)
- {
- if (changed)
- VEC_safe_push (varobj_p, *changed, existing);
- }
- else
- {
- if (new_and_unchanged)
- VEC_safe_push (varobj_p, *new_and_unchanged, existing);
- }
- }
+ Py_XDECREF (var->saved_item);
+ var->saved_item = item;
- do_cleanups (inner);
+ /* We want to truncate the child list just before this
+ element. */
+ break;
+ }
}
if (i < VEC_length (varobj_p, var->children))
{
- int i;
- children_changed = 1;
- for (i = 0; i < VEC_length (varobj_p, var->children); ++i)
- varobj_delete (VEC_index (varobj_p, var->children, i), NULL, 0);
+ int j;
+ *cchanged = 1;
+ for (j = i; j < VEC_length (varobj_p, var->children); ++j)
+ varobj_delete (VEC_index (varobj_p, var->children, j), NULL, 0);
+ VEC_truncate (varobj_p, var->children, i);
}
- VEC_truncate (varobj_p, var->children, i);
+
+ /* If there are fewer children than requested, note that the list of
+ children changed. */
+ if (to >= 0 && VEC_length (varobj_p, var->children) < to)
+ *cchanged = 1;
+
var->num_children = VEC_length (varobj_p, var->children);
do_cleanups (back_to);
- *cchanged = children_changed;
return 1;
#else
gdb_assert (0 && "should never be called if Python is not enabled");
@@ -961,20 +1082,26 @@ varobj_get_num_children (struct varobj *var)
{
if (var->num_children == -1)
{
- int changed;
- if (!var->pretty_printer
- || !update_dynamic_varobj_children (var, NULL, NULL, &changed))
+ if (var->pretty_printer)
+ {
+ int dummy;
+
+ /* If we have a dynamic varobj, don't report -1 children.
+ So, try to fetch some children first. */
+ update_dynamic_varobj_children (var, NULL, NULL, NULL, &dummy, 0, 0);
+ }
+ else
var->num_children = number_of_children (var);
}
- return var->num_children;
+ return var->num_children >= 0 ? var->num_children : 0;
}
/* Creates a list of the immediate children of a variable object;
the return code is the number of such children or -1 on error */
VEC (varobj_p)*
-varobj_list_children (struct varobj *var)
+varobj_list_children (struct varobj *var, int *from, int *to)
{
struct varobj *child;
char *name;
@@ -982,12 +1109,16 @@ varobj_list_children (struct varobj *var)
var->children_requested = 1;
- if (var->pretty_printer
+ if (var->pretty_printer)
+ {
/* This, in theory, can result in the number of children changing without
frontend noticing. But well, calling -var-list-children on the same
varobj twice is not something a sane frontend would do. */
- && update_dynamic_varobj_children (var, NULL, NULL, &children_changed))
- return var->children;
+ update_dynamic_varobj_children (var, NULL, NULL, NULL, &children_changed,
+ 0, *to);
+ restrict_range (var->children, from, to);
+ return var->children;
+ }
if (var->num_children == -1)
var->num_children = number_of_children (var);
@@ -1013,10 +1144,10 @@ varobj_list_children (struct varobj *var)
name = name_of_child (var, i);
existing = create_child (var, i, name);
VEC_replace (varobj_p, var->children, i, existing);
- install_default_visualizer (existing);
}
}
+ restrict_range (var->children, from, to);
return var->children;
}
@@ -1027,7 +1158,6 @@ varobj_add_child (struct varobj *var, const char *name, struct value *value)
VEC_length (varobj_p, var->children),
name, value);
VEC_safe_push (varobj_p, var->children, v);
- install_default_visualizer (v);
return v;
}
@@ -1089,6 +1219,12 @@ varobj_get_attributes (struct varobj *var)
return attributes;
}
+int
+varobj_pretty_printed_p (struct varobj *var)
+{
+ return var->pretty_printer != NULL;
+}
+
char *
varobj_get_formatted_value (struct varobj *var,
enum varobj_display_formats format)
@@ -1166,6 +1302,116 @@ varobj_set_value (struct varobj *var, char *expression)
return 1;
}
+#if HAVE_PYTHON
+
+/* A helper function to install a constructor function and visualizer
+ in a varobj. */
+
+static void
+install_visualizer (struct varobj *var, PyObject *constructor,
+ PyObject *visualizer)
+{
+ Py_XDECREF (var->constructor);
+ var->constructor = constructor;
+
+ Py_XDECREF (var->pretty_printer);
+ var->pretty_printer = visualizer;
+
+ Py_XDECREF (var->child_iter);
+ var->child_iter = NULL;
+}
+
+/* Install the default visualizer for VAR. */
+
+static void
+install_default_visualizer (struct varobj *var)
+{
+ if (pretty_printing)
+ {
+ PyObject *pretty_printer = NULL;
+
+ if (var->value)
+ {
+ pretty_printer = gdbpy_get_varobj_pretty_printer (var->value);
+ if (! pretty_printer)
+ {
+ gdbpy_print_stack ();
+ error (_("Cannot instantiate printer for default visualizer"));
+ }
+ }
+
+ if (pretty_printer == Py_None)
+ {
+ Py_DECREF (pretty_printer);
+ pretty_printer = NULL;
+ }
+
+ install_visualizer (var, NULL, pretty_printer);
+ }
+}
+
+/* Instantiate and install a visualizer for VAR using CONSTRUCTOR to
+ make a new object. */
+
+static void
+construct_visualizer (struct varobj *var, PyObject *constructor)
+{
+ PyObject *pretty_printer;
+
+ Py_INCREF (constructor);
+ if (constructor == Py_None)
+ pretty_printer = NULL;
+ else
+ {
+ pretty_printer = instantiate_pretty_printer (constructor, var->value);
+ if (! pretty_printer)
+ {
+ gdbpy_print_stack ();
+ Py_DECREF (constructor);
+ constructor = Py_None;
+ Py_INCREF (constructor);
+ }
+
+ if (pretty_printer == Py_None)
+ {
+ Py_DECREF (pretty_printer);
+ pretty_printer = NULL;
+ }
+ }
+
+ install_visualizer (var, constructor, pretty_printer);
+}
+
+#endif /* HAVE_PYTHON */
+
+/* A helper function for install_new_value. This creates and installs
+ a visualizer for VAR, if appropriate. */
+
+static void
+install_new_value_visualizer (struct varobj *var)
+{
+#if HAVE_PYTHON
+ /* If the constructor is None, then we want the raw value. If VAR
+ does not have a value, just skip this. */
+ if (var->constructor != Py_None && var->value)
+ {
+ struct cleanup *cleanup;
+ PyObject *pretty_printer = NULL;
+
+ cleanup = varobj_ensure_python_env (var);
+
+ if (!var->constructor)
+ install_default_visualizer (var);
+ else
+ construct_visualizer (var, var->constructor);
+
+ do_cleanups (cleanup);
+ }
+#else
+ /* Do nothing. */
+#endif
+}
+
/* Assign a new value to a variable object. If INITIAL is non-zero,
this is the first assignement after the variable object was just
created, or changed type. In that case, just assign the value
@@ -1206,10 +1452,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
that in C++ a reference is not rebindable, it cannot
meaningfully change. So, get hold of the real value. */
if (value)
- {
- value = coerce_ref (value);
- release_value (value);
- }
+ value = coerce_ref (value);
if (var->type && TYPE_CODE (var->type) == TYPE_CODE_UNION)
/* For unions, we need to fetch the value implicitly because
@@ -1256,7 +1499,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
values. Don't get string rendering if the value is
lazy -- if it is, the code above has decided that the value
should not be fetched. */
- if (value && !value_lazy (value))
+ if (value && !value_lazy (value) && !var->pretty_printer)
print_value = value_get_print_value (value, var->format, var);
/* If the type is changeable, compare the old and the new values.
@@ -1272,7 +1515,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
{
changed = 1;
}
- else
+ else if (! var->pretty_printer)
{
/* Try to compare the values. That requires that both
values are non-lazy. */
@@ -1317,74 +1560,53 @@ install_new_value (struct varobj *var, struct value *value, int initial)
if (var->value != NULL && var->value != value)
value_free (var->value);
var->value = value;
- if (var->print_value)
- xfree (var->print_value);
- var->print_value = print_value;
+ if (value != NULL)
+ value_incref (value);
if (value && value_lazy (value) && intentionally_not_fetched)
var->not_fetched = 1;
else
var->not_fetched = 0;
var->updated = 0;
+ install_new_value_visualizer (var);
+
+ /* If we installed a pretty-printer, re-compare the printed version
+ to see if the variable changed. */
+ if (var->pretty_printer)
+ {
+ xfree (print_value);
+ print_value = value_get_print_value (var->value, var->format, var);
+ if (!var->print_value || strcmp (var->print_value, print_value) != 0)
+ changed = 1;
+ }
+ if (var->print_value)
+ xfree (var->print_value);
+ var->print_value = print_value;
+
gdb_assert (!var->value || value_type (var->value));
return changed;
}
-static void
-install_visualizer (struct varobj *var, PyObject *visualizer)
+/* Return the requested range for a varobj. VAR is the varobj. FROM
+ and TO are out parameters; *FROM and *TO will be set to the
+ selected sub-range of VAR. If no range was selected using
+ -var-set-update-range, then both will be -1. */
+void
+varobj_get_child_range (struct varobj *var, int *from, int *to)
{
-#if HAVE_PYTHON
- /* If there are any children now, wipe them. */
- varobj_delete (var, NULL, 1 /* children only */);
- var->num_children = -1;
-
- Py_XDECREF (var->pretty_printer);
- var->pretty_printer = visualizer;
-
- install_new_value (var, var->value, 1);
-
- /* If we removed the visualizer, and the user ever requested the
- object's children, then we must compute the list of children.
- Note that we needn't do this when installing a visualizer,
- because updating will recompute dynamic children. */
- if (!visualizer && var->children_requested)
- varobj_list_children (var);
-#else
- error (_("Python support required"));
-#endif
+ *from = var->from;
+ *to = var->to;
}
-static void
-install_default_visualizer (struct varobj *var)
+/* Set the selected sub-range of children of VAR to start at index
+ FROM and end at index TO. If either FROM or TO is less than zero,
+ this is interpreted as a request for all children. */
+void
+varobj_set_child_range (struct varobj *var, int from, int to)
{
-#if HAVE_PYTHON
- struct cleanup *cleanup;
- PyObject *pretty_printer = NULL;
-
- cleanup = varobj_ensure_python_env (var);
-
- if (var->value)
- {
- pretty_printer = gdbpy_get_varobj_pretty_printer (var->value);
- if (! pretty_printer)
- {
- gdbpy_print_stack ();
- error (_("Cannot instantiate printer for default visualizer"));
- }
- }
-
- if (pretty_printer == Py_None)
- {
- Py_DECREF (pretty_printer);
- pretty_printer = NULL;
- }
-
- install_visualizer (var, pretty_printer);
- do_cleanups (cleanup);
-#else
- /* No error is right as this function is inserted just as a hook. */
-#endif
+ var->from = from;
+ var->to = to;
}
void
@@ -1402,31 +1624,19 @@ varobj_set_visualizer (struct varobj *var, const char *visualizer)
make_cleanup_py_decref (globals);
constructor = PyRun_String (visualizer, Py_eval_input, globals, globals);
-
- /* Do not instantiate NoneType. */
- if (constructor == Py_None)
- {
- pretty_printer = Py_None;
- Py_INCREF (pretty_printer);
- }
- else
- pretty_printer = instantiate_pretty_printer (constructor, var->value);
-
- Py_XDECREF (constructor);
- if (! pretty_printer)
+ if (! constructor)
{
gdbpy_print_stack ();
error (_("Could not evaluate visualizer expression: %s"), visualizer);
}
- if (pretty_printer == Py_None)
- {
- Py_DECREF (pretty_printer);
- pretty_printer = NULL;
- }
+ construct_visualizer (var, constructor);
+ Py_XDECREF (constructor);
- install_visualizer (var, pretty_printer);
+ /* If there are any children now, wipe them. */
+ varobj_delete (var, NULL, 1 /* children only */);
+ var->num_children = -1;
do_cleanups (back_to);
#else
@@ -1537,44 +1747,74 @@ VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit)
/* We probably should not get children of a varobj that has a
pretty-printer, but for which -var-list-children was never
- invoked. Presumably, such varobj is not yet expanded in the
- UI, so we need not bother getting it. */
+ invoked. */
if (v->pretty_printer)
{
- VEC (varobj_p) *changed = 0, *new_and_unchanged = 0;
+ VEC (varobj_p) *changed = 0, *new = 0, *unchanged = 0;
int i, children_changed;
varobj_p tmp;
- if (!v->children_requested)
- continue;
-
if (v->frozen)
continue;
+ if (!v->children_requested)
+ {
+ int dummy;
+
+ /* If we initially did not have potential children, but
+ now we do, consider the varobj as changed.
+ Otherwise, if children were never requested, consider
+ it as unchanged -- presumably, such varobj is not yet
+ expanded in the UI, so we need not bother getting
+ it. */
+ if (!varobj_has_more (v, 0))
+ {
+ update_dynamic_varobj_children (v, NULL, NULL, NULL,
+ &dummy, 0, 0);
+ if (varobj_has_more (v, 0))
+ r.changed = 1;
+ }
+
+ if (r.changed)
+ VEC_safe_push (varobj_update_result, result, &r);
+
+ continue;
+ }
+
/* If update_dynamic_varobj_children returns 0, then we have
a non-conforming pretty-printer, so we skip it. */
- if (update_dynamic_varobj_children (v, &changed, &new_and_unchanged,
- &children_changed))
+ if (update_dynamic_varobj_children (v, &changed, &new, &unchanged,
+ &children_changed, 1, v->to))
{
- if (children_changed)
- r.children_changed = 1;
- for (i = 0; VEC_iterate (varobj_p, changed, i, tmp); ++i)
+ if (children_changed || new)
{
- varobj_update_result r = {tmp};
- r.changed = 1;
- r.value_installed = 1;
- VEC_safe_push (varobj_update_result, stack, &r);
+ r.children_changed = 1;
+ r.new = new;
}
- for (i = 0;
- VEC_iterate (varobj_p, new_and_unchanged, i, tmp);
- ++i)
+ for (i = 0; VEC_iterate (varobj_p, changed, i, tmp); ++i)
{
varobj_update_result r = {tmp};
+ r.changed = 1;
r.value_installed = 1;
VEC_safe_push (varobj_update_result, stack, &r);
}
+ for (i = 0; VEC_iterate (varobj_p, unchanged, i, tmp); ++i)
+ {
+ if (!tmp->frozen)
+ {
+ varobj_update_result r = {tmp};
+ r.value_installed = 1;
+ VEC_safe_push (varobj_update_result, stack, &r);
+ }
+ }
if (r.changed || r.children_changed)
VEC_safe_push (varobj_update_result, result, &r);
+
+ /* Free CHANGED and UNCHANGED, but not NEW, because NEW
+ has been put into the result vector. */
+ VEC_free (varobj_p, changed);
+ VEC_free (varobj_p, unchanged);
+
continue;
}
}
@@ -1862,7 +2102,12 @@ new_variable (void)
var->frozen = 0;
var->not_fetched = 0;
var->children_requested = 0;
+ var->from = -1;
+ var->to = -1;
+ var->constructor = 0;
var->pretty_printer = 0;
+ var->child_iter = 0;
+ var->saved_item = 0;
return var;
}
@@ -1892,7 +2137,10 @@ free_variable (struct varobj *var)
if (var->pretty_printer)
{
struct cleanup *cleanup = varobj_ensure_python_env (var);
- Py_DECREF (var->pretty_printer);
+ Py_XDECREF (var->constructor);
+ Py_XDECREF (var->pretty_printer);
+ Py_XDECREF (var->child_iter);
+ Py_XDECREF (var->saved_item);
do_cleanups (cleanup);
}
#endif
@@ -2139,6 +2387,8 @@ value_of_root (struct varobj **var_handle, int *type_changed)
else
{
tmp_var->obj_name = xstrdup (var->obj_name);
+ tmp_var->from = var->from;
+ tmp_var->to = var->to;
varobj_delete (var, NULL, 0);
install_variable (tmp_var);
@@ -2173,7 +2423,11 @@ static char *
my_value_of_variable (struct varobj *var, enum varobj_display_formats format)
{
if (var->root->is_valid)
- return (*var->root->lang->value_of_variable) (var, format);
+ {
+ if (var->pretty_printer)
+ return value_get_print_value (var->value, var->format, var);
+ return (*var->root->lang->value_of_variable) (var, format);
+ }
else
return NULL;
}
@@ -2196,43 +2450,51 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
struct cleanup *back_to = varobj_ensure_python_env (var);
PyObject *value_formatter = var->pretty_printer;
- if (value_formatter && PyObject_HasAttr (value_formatter,
- gdbpy_to_string_cst))
+ if (value_formatter)
{
- char *hint;
- struct value *replacement;
- int string_print = 0;
- PyObject *output = NULL;
+ /* First check to see if we have any children at all. If so,
+ we simply return {...}. */
+ if (dynamic_varobj_has_child_method (var))
+ return xstrdup ("{...}");
- hint = gdbpy_get_display_hint (value_formatter);
- if (hint)
+ if (PyObject_HasAttr (value_formatter, gdbpy_to_string_cst))
{
- if (!strcmp (hint, "string"))
- string_print = 1;
- xfree (hint);
- }
+ char *hint;
+ struct value *replacement;
+ int string_print = 0;
+ PyObject *output = NULL;
+
+ hint = gdbpy_get_display_hint (value_formatter);
+ if (hint)
+ {
+ if (!strcmp (hint, "string"))
+ string_print = 1;
+ xfree (hint);
+ }
- output = apply_varobj_pretty_printer (value_formatter,
- &replacement);
- if (output)
- {
- PyObject *py_str = python_string_to_target_python_string (output);
- if (py_str)
- {
- char *s = PyString_AsString (py_str);
- len = PyString_Size (py_str);
- thevalue = xmemdup (s, len + 1, len + 1);
- Py_DECREF (py_str);
+ output = apply_varobj_pretty_printer (value_formatter,
+ &replacement);
+ if (output)
+ {
+ PyObject *py_str
+ = python_string_to_target_python_string (output);
+ if (py_str)
+ {
+ char *s = PyString_AsString (py_str);
+ len = PyString_Size (py_str);
+ thevalue = xmemdup (s, len + 1, len + 1);
+ Py_DECREF (py_str);
+ }
+ Py_DECREF (output);
}
- Py_DECREF (output);
- }
- if (thevalue && !string_print)
- {
- do_cleanups (back_to);
- return thevalue;
+ if (thevalue && !string_print)
+ {
+ do_cleanups (back_to);
+ return thevalue;
+ }
+ if (replacement)
+ value = replacement;
}
- if (replacement)
- value = replacement;
}
do_cleanups (back_to);
}
@@ -2961,10 +3223,7 @@ cplus_describe_child (struct varobj *parent, int index,
*cname = xstrdup (TYPE_FIELD_NAME (type, index));
if (cvalue && value)
- {
- *cvalue = value_cast (TYPE_FIELD_TYPE (type, index), value);
- release_value (*cvalue);
- }
+ *cvalue = value_cast (TYPE_FIELD_TYPE (type, index), value);
if (ctype)
{
diff --git a/gdb/varobj.h b/gdb/varobj.h
index 7297243..f43c593 100644
--- a/gdb/varobj.h
+++ b/gdb/varobj.h
@@ -78,6 +78,12 @@ typedef struct varobj_update_result_t
new value of varobj is already computed and installed, or has to
be yet installed. Don't use this outside varobj.c */
int value_installed;
+
+ /* This will be non-NULL when new children were added to the varobj.
+ It lists the new children (which must necessarily come at the end
+ of the child list) added during an update. The caller is
+ responsible for freeing this vector. */
+ VEC (varobj_p) *new;
} varobj_update_result;
DEF_VEC_O (varobj_update_result);
@@ -112,13 +118,24 @@ extern void varobj_set_frozen (struct varobj *var, int frozen);
extern int varobj_get_frozen (struct varobj *var);
+extern void varobj_get_child_range (struct varobj *var, int *from, int *to);
+
+extern void varobj_set_child_range (struct varobj *var, int from, int to);
+
extern char *varobj_get_display_hint (struct varobj *var);
extern int varobj_get_num_children (struct varobj *var);
-/* Return the list of children of VAR. The returned vector
- should not be modified in any way. */
-extern VEC (varobj_p)* varobj_list_children (struct varobj *var);
+/* Return the list of children of VAR. The returned vector should not
+ be modified in any way. FROM and TO are in/out parameters
+ indicating the range of children to return. If either *FROM or *TO
+ is less than zero on entry, then all children will be returned. On
+ return, *FROM and *TO will be updated to indicate the real range
+ that was returned. The resulting VEC will contain at least the
+ children from *FROM to just before *TO; it might contain more
+ children, depending on whether any more were available. */
+extern VEC (varobj_p)* varobj_list_children (struct varobj *var,
+ int *from, int *to);
extern char *varobj_get_type (struct varobj *var);
@@ -149,6 +166,13 @@ extern int varobj_editable_p (struct varobj *var);
extern int varobj_floating_p (struct varobj *var);
-extern void varobj_set_visualizer (struct varobj *var, const char *visualizer);
+extern void
+varobj_set_visualizer (struct varobj *var, const char *visualizer);
+
+extern void varobj_enable_pretty_printing (void);
+
+extern int varobj_has_more (struct varobj *var, int to);
+
+extern int varobj_pretty_printed_p (struct varobj *var);
#endif /* VAROBJ_H */
^ permalink raw reply [flat|nested] 39+ messages in thread
* Patch: implement new dynamic varobj spec
2009-09-10 20:58 Patch: implement new dynamic varobj spec Tom Tromey
@ 2009-09-11 5:41 ` Nick Roberts
2009-09-11 19:41 ` Tom Tromey
2009-09-14 19:56 ` Patch: implement new dynamic varobj spec Tom Tromey
2009-09-12 9:18 ` Eli Zaretskii
` (3 subsequent siblings)
4 siblings, 2 replies; 39+ messages in thread
From: Nick Roberts @ 2009-09-11 5:41 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
Tom Tromey writes:
> This is the long-awaited dynamic varobj patch.
> It implements the spec as described by Vladimir:
>
> http://sourceware.org/ml/gdb/2009-07/msg00088.html
It's a big patch. Dynamic variable objects seem to behave differently
to the current ones:
1) Children are reported (and presumably created) in var-update even though
only a root variable object may have been created, i.e., not
-var-list-children has been invoked.
2) -var-update seems to list changes to children of dynamic objects in reverse
numerical order.
Does -var-set-update-range only work for dynamic variable objects - the
documentation doesn't say but I couldn't get it to work with current ones.
With dynamic variable objects I could restrict the range but it didn't seem
to match up (from seem to be ignored).
The new FROM TO arguments for -var-list-children work with current variable
objects but it seems that GDB just restricts what it prints but stores the
whole vector which doesn't seem to save memory. Would it not be better to
create children in the range specified since the array might be large and the
front end only needs the values it displays.
Likewise with -var-set-update-range: does GDB track all changes and just
report a restricted set, or restrict what it tracks?
I have a few thoughts about the documentation:
The field `in_scope' is already described with three possible values. It's
described again with just two.
The field `displayhint' seems very useful with -var-create but does it serve
any purpose when output with -var-update?
The field `has_more' seems to be overloaded depending on whether its output
from -var-create, -var-list-children or -var-update.
Existing documentation uses @var for field names, while new uses @samp.
I find varobj.c hard to read and some of what I say might be wrong but
hopefully there's more signal than noise.
--
Nick http://www.inet.net.nz/~nickrob
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-11 5:41 ` Nick Roberts
@ 2009-09-11 19:41 ` Tom Tromey
2009-09-11 20:49 ` Eli Zaretskii
2009-09-11 23:55 ` Nick Roberts
2009-09-14 19:56 ` Patch: implement new dynamic varobj spec Tom Tromey
1 sibling, 2 replies; 39+ messages in thread
From: Tom Tromey @ 2009-09-11 19:41 UTC (permalink / raw)
To: Nick Roberts; +Cc: gdb-patches
>>>>> "Nick" == Nick Roberts <nickrob@snap.net.nz> writes:
Nick> Dynamic variable objects seem to behave differently to the current
Nick> ones:
Yeah.
Nick> 1) Children are reported (and presumably created) in var-update
Nick> even though only a root variable object may have been created,
Nick> i.e., not -var-list-children has been invoked.
It should only report children if you previously requested them.
It may create a child at any time by asking the Python printer; but a
child created this way won't be reported. This is needed to properly
report has_more.
Nick> 2) -var-update seems to list changes to children of dynamic
Nick> objects in reverse numerical order.
Oh, odd. But not a bug, really, as the order is not specified.
Nick> Does -var-set-update-range only work for dynamic variable objects
Nick> - the documentation doesn't say but I couldn't get it to work with
Nick> current ones.
Yeah, I think it ought to work. I'm not sure how useful it is, though.
Nick> With dynamic variable objects I could restrict the
Nick> range but it didn't seem to match up (from seem to be ignored).
I will look into this.
Nick> The new FROM TO arguments for -var-list-children work with current
Nick> variable objects but it seems that GDB just restricts what it
Nick> prints but stores the whole vector which doesn't seem to save
Nick> memory. Would it not be better to create children in the range
Nick> specified since the array might be large and the front end only
Nick> needs the values it displays.
We designed a very simple Python API that does not support random
access. The reason for this is that a simple API is easier for users.
Naturally, this is an arguable decision.
The real intent for limiting the range is not to save memory but to
avoid problems printing uninitialized containers. I think a front end
ought to always restrict the range when fetching the children of a
dynamic varobj. I suppose I will update the documentation to say this.
For dynamic varobjs, we do save a bit of memory because the TO argument
limits how many children we compute.
Nick> Likewise with -var-set-update-range: does GDB track all changes
Nick> and just report a restricted set, or restrict what it tracks?
It always starts over at 0, and then filters on the low side after
computing differences. On the high side, TO (really TO+1, due to
has_more computation) limits how many children we fetch.
Nick> I have a few thoughts about the documentation:
Thanks, I'll fix these.
Nick> The field `displayhint' seems very useful with -var-create but
Nick> does it serve any purpose when output with -var-update?
It could change -- bizarre but in theory possible.
Nick> The field `has_more' seems to be overloaded depending on whether
Nick> its output from -var-create, -var-list-children or -var-update.
How do you mean? I think it means pretty much the same thing in all
cases: it is true if the object has children beyond what you've
requested.
Nick> Existing documentation uses @var for field names, while new uses @samp.
Yeah. @var seems clearly wrong there.
I will change the new code though.
Nick> I find varobj.c hard to read
Yes, me too.
Tom
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-11 19:41 ` Tom Tromey
@ 2009-09-11 20:49 ` Eli Zaretskii
2009-09-11 21:12 ` Tom Tromey
2009-09-11 23:55 ` Nick Roberts
1 sibling, 1 reply; 39+ messages in thread
From: Eli Zaretskii @ 2009-09-11 20:49 UTC (permalink / raw)
To: Tom Tromey; +Cc: nickrob, gdb-patches
> From: Tom Tromey <tromey@redhat.com>
> Cc: gdb-patches@sourceware.org
> Date: Fri, 11 Sep 2009 13:40:23 -0600
>
> Nick> Existing documentation uses @var for field names, while new uses @samp.
>
> Yeah. @var seems clearly wrong there.
> I will change the new code though.
What part of the patch does this refer to? I didn't yet read the
patch carefully, but just skimming it I don't see any wrong @var.
Please be more specific.
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-11 20:49 ` Eli Zaretskii
@ 2009-09-11 21:12 ` Tom Tromey
2009-09-12 8:08 ` Eli Zaretskii
0 siblings, 1 reply; 39+ messages in thread
From: Tom Tromey @ 2009-09-11 21:12 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: nickrob, gdb-patches
>>>>> "Eli" == Eli Zaretskii <eliz@gnu.org> writes:
Nick> Existing documentation uses @var for field names, while new uses @samp.
>> Yeah. @var seems clearly wrong there.
>> I will change the new code though.
Eli> What part of the patch does this refer to? I didn't yet read the
Eli> patch carefully, but just skimming it I don't see any wrong @var.
Eli> Please be more specific.
He is saying that the patch has additions like:
@table @samp
@item name
The name of the varobj.
... but existing MI documentation uses @table @var.
Tom
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-11 19:41 ` Tom Tromey
2009-09-11 20:49 ` Eli Zaretskii
@ 2009-09-11 23:55 ` Nick Roberts
2009-09-14 19:59 ` Tom Tromey
1 sibling, 1 reply; 39+ messages in thread
From: Nick Roberts @ 2009-09-11 23:55 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
> Nick> 1) Children are reported (and presumably created) in var-update
> Nick> even though only a root variable object may have been created,
> Nick> i.e., not -var-list-children has been invoked.
>
> It should only report children if you previously requested them.
You're probably right, I can't reproduce this now. I've been testing on
archer-tromey-python branch at git://sourceware.org/git/archer.git as I've
presumed that's where the patch posted here came from.
Incidentally git is a great improvement: I noticed that variable objects are
now staying in scope when the executable restarted and couldn't see why. I
used 'git bisect' starting with 2000 revisions to find that it was due to Jan
Kratochvil's patch disabling randomisation. I don't think I could have done
that with gdb in CVS. I don't know how up to date the git mirror stays but it
would be grat if we could move to it at some point. There appear to be lots
of other benefits.
>...
> Nick> Existing documentation uses @var for field names, while new uses @samp.
>
> Yeah. @var seems clearly wrong there.
> I will change the new code though.
Really? I thought @samp was wrong. Eli will know.
I would really like to use these improvements in Emacs but the release isn't
far away. So I would request that -enable-pretty-printing is marked as an
EXPERIMENTAL feature in the manual. That way changes can be made without
anyone complaining. Maybe by 7.1 early next year there will be frontends
that have worked out how to use it and that marking could be removed.
--
Nick http://www.inet.net.nz/~nickrob
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-11 21:12 ` Tom Tromey
@ 2009-09-12 8:08 ` Eli Zaretskii
0 siblings, 0 replies; 39+ messages in thread
From: Eli Zaretskii @ 2009-09-12 8:08 UTC (permalink / raw)
To: Tom Tromey; +Cc: nickrob, gdb-patches
> From: Tom Tromey <tromey@redhat.com>
> Cc: nickrob@snap.net.nz, gdb-patches@sourceware.org
> Date: Fri, 11 Sep 2009 15:11:51 -0600
>
> @table @samp
> @item name
> The name of the varobj.
>
> ... but existing MI documentation uses @table @var.
Then you are right: "@table @var" is against the conventions. Sorry I
didn't see that earlier.
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-10 20:58 Patch: implement new dynamic varobj spec Tom Tromey
2009-09-11 5:41 ` Nick Roberts
@ 2009-09-12 9:18 ` Eli Zaretskii
2009-09-14 20:03 ` Tom Tromey
2009-09-14 11:24 ` Vladimir Prus
` (2 subsequent siblings)
4 siblings, 1 reply; 39+ messages in thread
From: Eli Zaretskii @ 2009-09-12 9:18 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
> From: Tom Tromey <tromey@redhat.com>
> Date: Thu, 10 Sep 2009 14:58:05 -0600
>
> This is the long-awaited dynamic varobj patch.
> It implements the spec as described by Vladimir:
>
> http://sourceware.org/ml/gdb/2009-07/msg00088.html
Thanks.
> This patch needs a doc review.
Sorry for a delay in providing this review.
> +Once sent, this command cannot be undone.
A minor stylistic nit: I suggest the following variant:
Once enabled, this feature cannot be disabled.
> +Note that if Python support has not been compiled into @value{GDBN},
> +this command will still succeed.
Suggest to add "(and do nothing)" to the end of the sentence
Btw, does this silent failure have good reasons?
> +This operation returns attributes of the newly-created varobj. These
> +include, but are not limited to:
Why don't we have an exhaustive list here?
> +@item thread-id
> +If a fixed variable object is bound to a specific thread, then this is
> +the thread's identifier.
Is "fixed" used here as opposed to "dynamic"? If so, it would be a
good idea to say explicitly what, if anything, this attribute means
for a dynamic varobj. (If that's not the intent, please explain the
significance of the word "fixed" here; I cannot find "fixed varobj"
anywhere else in the manual.)
> +reset and all children will be reported. Otherwise, children starting
> +at @var{from} (zero-based) and ending just before @var{to} will be
> +reported.
Since "ending just before" is a bit ambiguous, suggest to reword
thusly:
Otherwise, children starting at @var{from} (zero-based) and up to
and excluding @var{to} will be reported.
> +If a child range is requested, it will not affect the range of
> +children reported by a future call to @code{-var-update}.
Would it be better to say explicitly that only the current calls are
affected? Like this:
If a child range is requested, it will only affect the current call
to @code{-var-update}, but not the future calls.
> +For a dynamic varobj, this value cannot reliably be used to form an
> +expression. Also, a dynamic varobj will not report the access
> +qualifying pseudo-children, regardless of the language.
Do we want to give the reader some hints as to how to achieve these
with dynamic varobjs?
> +A dynamic varobj can supply a display hint to the front end. The
> +comes directly from the Python pretty-printer object's
> +@code{display_hint} method. @xref{Pretty Printing}.
Something is missing in the second sentence.
> +children will be reported. Otherwise, children starting at @var{from}
> +(zero-based) and ending just before @var{to} will be reported.
Same comment as above about "ending just before".
Finally, I think we need a @cindex entry for "dynamic varobj" pointing
to the section where they are introduced (with a @dfn).
Thanks.
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-10 20:58 Patch: implement new dynamic varobj spec Tom Tromey
2009-09-11 5:41 ` Nick Roberts
2009-09-12 9:18 ` Eli Zaretskii
@ 2009-09-14 11:24 ` Vladimir Prus
2009-09-16 23:53 ` Tom Tromey
2009-09-14 20:05 ` Tom Tromey
2009-09-18 9:29 ` Vladimir Prus
4 siblings, 1 reply; 39+ messages in thread
From: Vladimir Prus @ 2009-09-14 11:24 UTC (permalink / raw)
To: gdb-patches
Tom Tromey wrote:
> This is the long-awaited dynamic varobj patch.
> It implements the spec as described by Vladimir:
>
> http://sourceware.org/ml/gdb/2009-07/msg00088.html
>
> .. with various minor changes we've discussed on that thread and
> elsewhere. I didn't give the follow-up URLs; I think that the doc patch
> ought to be sufficient, and if it isn't, I will fix it up.
>
> This has been in development for quite a while, including testing using
> two different MI consumers (Vladimir's and one by Noam Yorav-Raphael).
>
> There are three outstanding bugs.
>
> * A dynamic varobj bug that I couldn't reproduce
> http://sourceware.org/ml/archer/2009-q3/msg00169.html
>
> * Lazy string printing.
> http://sourceware.org/ml/archer/2009-q3/msg00189.html
> I'm not sure what we'll do about this in the 7.0 timeframe, maybe
> nothing.
>
> * -var-info-path-expression doesn't work
> http://sourceware.org/bugzilla/show_bug.cgi?id=10252
> (I am not sure it can be made to work, I was planning to turn it into
> an error.)
>
>
> This patch needs a doc review.
>
> This patch doesn't apply directly due to the big python renaming.
> You can probably run sed on the patch if you care to try it.
For avoidance of doubt, I think this patch should go in. I plan to read
the doc changes, and glance at the code, but I am fairly confident that this
is overall good.
- Volodya
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-11 5:41 ` Nick Roberts
2009-09-11 19:41 ` Tom Tromey
@ 2009-09-14 19:56 ` Tom Tromey
1 sibling, 0 replies; 39+ messages in thread
From: Tom Tromey @ 2009-09-14 19:56 UTC (permalink / raw)
To: Nick Roberts; +Cc: gdb-patches
>>>>> "Nick" == Nick Roberts <nickrob@snap.net.nz> writes:
Nick> Would it not be better to create children in the range specified
Nick> since the array might be large and the front end only needs the
Nick> values it displays.
I think I glossed over this in my earlier reply.
Yeah, I think this would be a good improvement for ordinary
(non-pretty-printed) arrays. I have not looked into the problem, though
-- I've really just focused on the dynamic / pretty-printing bits.
Tom
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-11 23:55 ` Nick Roberts
@ 2009-09-14 19:59 ` Tom Tromey
2009-09-14 22:55 ` Nick Roberts
2009-09-16 5:44 ` Vladimir Prus
0 siblings, 2 replies; 39+ messages in thread
From: Tom Tromey @ 2009-09-14 19:59 UTC (permalink / raw)
To: Nick Roberts; +Cc: gdb-patches
>>>>> "Nick" == Nick Roberts <nickrob@snap.net.nz> writes:
Nick> I would really like to use these improvements in Emacs but the
Nick> release isn't far away. So I would request that
Nick> -enable-pretty-printing is marked as an EXPERIMENTAL feature in
Nick> the manual. That way changes can be made without anyone
Nick> complaining. Maybe by 7.1 early next year there will be frontends
Nick> that have worked out how to use it and that marking could be
Nick> removed.
I think we've been conservative enough about this code that it is
probably reasonable to let people rely on it. It has been through a lot
of vetting.
However, I don't mind adding a note to the manual if other maintainers
want that.
Tom
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-12 9:18 ` Eli Zaretskii
@ 2009-09-14 20:03 ` Tom Tromey
2009-09-14 20:22 ` Eli Zaretskii
0 siblings, 1 reply; 39+ messages in thread
From: Tom Tromey @ 2009-09-14 20:03 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches
>>>>> "Eli" == Eli Zaretskii <eliz@gnu.org> writes:
Tom> +Note that if Python support has not been compiled into @value{GDBN},
Tom> +this command will still succeed.
Eli> Suggest to add "(and do nothing)" to the end of the sentence
Eli> Btw, does this silent failure have good reasons?
There just didn't seem to be much value in issuing an error.
Tom> +This operation returns attributes of the newly-created varobj. These
Tom> +include, but are not limited to:
Eli> Why don't we have an exhaustive list here?
We may add attributes later.
Tom> +@item thread-id
Tom> +If a fixed variable object is bound to a specific thread, then this is
Tom> +the thread's identifier.
Eli> Is "fixed" used here as opposed to "dynamic"?
I don't know where that came from, I removed the "fixed".
Tom> +For a dynamic varobj, this value cannot reliably be used to form an
Tom> +expression. Also, a dynamic varobj will not report the access
Tom> +qualifying pseudo-children, regardless of the language.
Eli> Do we want to give the reader some hints as to how to achieve these
Eli> with dynamic varobjs?
There is no way to do these.
Tom
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-10 20:58 Patch: implement new dynamic varobj spec Tom Tromey
` (2 preceding siblings ...)
2009-09-14 11:24 ` Vladimir Prus
@ 2009-09-14 20:05 ` Tom Tromey
2009-09-14 20:24 ` Eli Zaretskii
2009-09-14 23:58 ` Nick Roberts
2009-09-18 9:29 ` Vladimir Prus
4 siblings, 2 replies; 39+ messages in thread
From: Tom Tromey @ 2009-09-14 20:05 UTC (permalink / raw)
To: gdb-patches
Here is a new version of this patch.
I tried to address all the documentation comments.
Also, I fixed the bug that Nick reported whereby the "from" parameter of
-var-set-update-range did not seem to have any effect. I added a
regression test for this.
Let me know what you think.
Tom
2009-09-10 Tom Tromey <tromey@redhat.com>
* varobj.h (varobj_update_result_t) <new>: New field.
(varobj_get_child_range, varobj_set_child_range): Declare.
(varobj_list_children): Update.
(varobj_enable_pretty_printing, varobj_has_more)
(varobj_pretty_printed_p): Declare.
* varobj.c (pretty_printing): New global.
(varobj_enable_pretty_printing): New function.
(struct varobj_root) <from, to, constructor, child_iter,
saved_item>: New fields.
(varobj_create): Don't call install_default_visualizer.
(instantiate_pretty_printer): Don't use value_copy.
(varobj_has_more): New function.
(restrict_range): New function.
(install_dynamic_child): Likewise.
(dynamic_varobj_has_child_method): Likewise.
(update_dynamic_varobj_children): Remove 'new_and_unchanged'
argument; add 'new', 'unchanged', 'from', and 'to' arguments.
Rewrite.
(varobj_get_num_children): Call update_dynamic_varobj_children.
(varobj_list_children): Add 'from' and 'to' arguments. Ignore
result of update_dynamic_varobj_children. Don't call
install_default_visualizer. Restrict result range.
(varobj_add_child): Don't call install_default_visualizer.
(varobj_pretty_printed_p): New function.
(install_visualizer): Rewrite. Move earlier in file.
(install_default_visualizer): Likewise.
(construct_visualizer): New function.
(install_new_value_visualizer): Likewise.
(install_new_value): Don't call release_value. Special case
pretty-printed objects. Use value_incref. Rearrange "changed"
logic.
(varobj_get_child_range): New function.
(varobj_set_child_range): Likewise.
(varobj_set_visualizer): Rewrite.
(varobj_update): Rewrite pretty-printing logic.
(new_variable): Initialize new fields.
(free_variable): Destroy new fields.
(value_of_root): Copy 'from' and 'to'.
(my_value_of_variable): Handle pretty-printers.
(value_get_print_value): Rework pretty-printing logic.
(cplus_describe_child): Don't use release_value.
* mi/mi-cmds.h (mi_cmd_enable_pretty_printing)
(mi_cmd_var_set_update_range): Declare.
* mi/mi-cmds.c (mi_cmds): Add enable-pretty-printing and
var-set-update-range.
* mi/mi-cmd-var.c (print_varobj): Update. Emit "dynamic"
attribute.
(mi_cmd_var_create): Emit "has_more" attribute.
(mi_cmd_var_set_format): Plug memory leak.
(mi_print_value_p): Replace 'type' argument with 'var'. Handle
pretty-printed varobjs.
(mi_cmd_var_list_children): Accept 'from' and 'to' arguments.
Emit "has_more" attribute.
(mi_cmd_var_evaluate_expression): Plug memory leak.
(mi_cmd_var_assign): Likewise.
(varobj_update_one): Likewise. Emit "dynamic", "has_more", and
"new_children" attributes.
(mi_cmd_enable_pretty_printing): New function.
(mi_cmd_var_set_update_range): Likewise.
2009-09-10 Tom Tromey <tromey@redhat.com>
* gdb.texinfo (GDB/MI Variable Objects): Document
-enable-pretty-printing, -var-set-update-range, dynamic varobjs.
Expand -var-update documentation.
2009-09-10 Tom Tromey <tromey@redhat.com>
* lib/mi-support.exp (mi_create_varobj): Update.
(mi_create_floating_varobj): Likewise.
(mi_create_dynamic_varobj): New proc.
(mi_varobj_update): Update.
(mi_varobj_update_with_type_change): Likewise.
(mi_varobj_update_kv_helper): New proc.
(mi_varobj_update_dynamic_helper): Rewrite.
(mi_varobj_update_dynamic): New proc.
(mi_list_varobj_children): Update.
(mi_list_varobj_children_range): Add 'from' and 'to' arguments.
* gdb.python/python-prettyprint.py (pp_outer): New class.
(pp_nullstr): Likewise.
(lookup_function): Register new printers.
* gdb.python/python-prettyprint.c (struct substruct): New type.
(struct outerstruct): Likewise.
(substruct_test): New function.
(struct nullstr): New type.
(string_1, string_2): New globals.
(main): Add new tests.
* gdb.python/python-mi.exp: Added regression tests.
* gdb.mi/mi2-var-display.exp: Update.
* gdb.mi/mi2-var-cmd.exp: Update.
* gdb.mi/mi2-var-child.exp: Update.
* gdb.mi/mi2-var-block.exp: Update.
* gdb.mi/mi-var-invalidate.exp: Update.
* gdb.mi/mi-var-display.exp: Update.
* gdb.mi/mi-var-cmd.exp: Update.
* gdb.mi/mi-var-child.exp: Update.
* gdb.mi/mi-var-block.exp: Update.
* gdb.mi/mi-break.exp: Update.
* gdb.mi/gdb701.exp: Update.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 7b26675..51a3524 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -23360,6 +23360,8 @@ access this functionality:
@item @strong{Operation}
@tab @strong{Description}
+@item @code{-enable-pretty-printing}
+@tab enable Python-based pretty-printing
@item @code{-var-create}
@tab create a variable object
@item @code{-var-delete}
@@ -23388,6 +23390,8 @@ access this functionality:
@tab update the variable and its children
@item @code{-var-set-frozen}
@tab set frozeness attribute
+@item @code{-var-set-update-range}
+@tab set range of children to display on update
@end multitable
In the next subsection we describe each operation in detail and suggest
@@ -23395,6 +23399,23 @@ how it can be used.
@subheading Description And Use of Operations on Variable Objects
+@subheading The @code{-enable-pretty-printing} Command
+@findex -enable-pretty-printing
+
+@smallexample
+-enable-pretty-printing
+@end smallexample
+
+@value{GDBN} allows Python-based visualizers to affect the output of the
+MI variable object commands. However, because there was no way to
+implement this in a fully backward-compatible way, a front end must
+request that this functionality be enabled.
+
+Once enabled, this feature cannot be disabled.
+
+Note that if Python support has not been compiled into @value{GDBN},
+this command will still succeed (and do nothing).
+
@subheading The @code{-var-create} Command
@findex -var-create
@@ -23434,15 +23455,56 @@ begin with a @samp{*}), or one of the following:
@samp{$@var{regname}} --- a CPU register name
@end itemize
+@cindex dynamic varobj
+A varobj's contents may be provided by a Python-based pretty-printer. In this
+case the varobj is known as a @dfn{dynamic varobj}. Dynamic varobjs
+have slightly different semantics in some cases. If the
+@code{-enable-pretty-printing} command is not sent, then @value{GDBN}
+will never create a dynamic varobj. This ensures backward
+compatibility for existing clients.
+
@subsubheading Result
-This operation returns the name, number of children and the type of the
-object created. Type is returned as a string as the ones generated by
-the @value{GDBN} CLI. If a fixed variable object is bound to a
-specific thread, the thread is is also printed:
+This operation returns attributes of the newly-created varobj. These
+include, but are not limited to:
+
+@table @samp
+@item name
+The name of the varobj.
+
+@item numchild
+The number of children of the varobj. This number is not necessarily
+reliable for a dynamic varobj. Instead, you must examine the
+@samp{has_more} attribute.
+
+@item value
+The varobj's scalar value. For a varobj whose type is some sort of
+aggregate (e.g., a @code{struct}), or for a dynamic varobj, this value
+will not be interesting.
+
+@item type
+The varobj's type. This is a string representation of the type, as
+would be printed by the @value{GDBN} CLI.
+
+@item thread-id
+If a variable object is bound to a specific thread, then this is the
+thread's identifier.
+
+@item has_more
+For a dynamic varobj, this indicates whether there appear to be any
+children available. For a non-dynamic varobj, this will be 0.
+
+@item dynamic
+This attribute will be present and have the value @samp{1} if the
+varobj is a dynamic varobj. If the varobj is not a dynamic varobj,
+then this attribute will not be present.
+@end table
+
+Typical output will look like this:
@smallexample
- name="@var{name}",numchild="@var{N}",type="@var{type}",thread-id="@var{M}"
+ name="@var{name}",numchild="@var{N}",type="@var{type}",thread-id="@var{M}",
+ has_more="@var{has_more}"
@end smallexample
@@ -23520,6 +23582,10 @@ Returns the number of children of a variable object @var{name}:
numchild=@var{n}
@end smallexample
+Note that this number is not completely reliable for a dynamic varobj.
+It will return the current number of children, but more children may
+be available.
+
@subheading The @code{-var-list-children} Command
@findex -var-list-children
@@ -23527,7 +23593,7 @@ Returns the number of children of a variable object @var{name}:
@subsubheading Synopsis
@smallexample
- -var-list-children [@var{print-values}] @var{name}
+ -var-list-children [@var{print-values}] @var{name} [@var{from} @var{to}]
@end smallexample
@anchor{-var-list-children}
@@ -23540,6 +23606,22 @@ values; and if it is 2 or @code{--simple-values} print the name and
value for simple data types and just the name for arrays, structures
and unions.
+@var{from} and @var{to}, if specified, indicate the range of children
+to report. If @var{from} or @var{to} is less than zero, the range is
+reset and all children will be reported. Otherwise, children starting
+at @var{from} (zero-based) and up to and excluding @var{to} will be
+reported.
+
+If a child range is requested, it will only affect the current call to
+@code{-var-list-children}, but not future calls to @code{-var-update}.
+For this, you must instead use @code{-var-set-update-range}. The
+intent of this approach is to enable a front end to implement any
+update approach it likes; for example, scrolling a view may cause the
+front end to request more children with @code{-var-list-children}, and
+then the front end could call @code{-var-set-update-range} with a
+different range to ensure that future updates are restricted to just
+the visible items.
+
For each child the following results are returned:
@table @var
@@ -23556,8 +23638,13 @@ designate access qualifiers. For these pseudo children @var{exp} is
@samp{public}, @samp{private}, or @samp{protected}. In this case the
type and value are not present.
+For a dynamic varobj, this value cannot reliably be used to form an
+expression. Also, a dynamic varobj will not report the access
+qualifying pseudo-children, regardless of the language.
+
@item numchild
-Number of children this child has.
+Number of children this child has. For a dynamic varobj, this will be
+0.
@item type
The type of the child.
@@ -23573,6 +23660,19 @@ Otherwise this result is not present.
If the variable object is frozen, this variable will be present with a value of 1.
@end table
+The result may have its own attributes:
+
+@table @samp
+@item displayhint
+A dynamic varobj can supply a display hint to the front end. The
+value comes directly from the Python pretty-printer object's
+@code{display_hint} method. @xref{Pretty Printing}.
+
+@item has_more
+This is an integer attribute which is nonzero if there are children
+remaining after the end of the selected range.
+@end table
+
@subsubheading Example
@smallexample
@@ -23649,6 +23749,9 @@ result can be used only for UI presentation. Typical use of
the @code{-var-info-path-expression} command is creating a
watchpoint from a variable object.
+This command is currently not valid for children of a dynamic varobj,
+and will give an error when invoked on one.
+
For example, suppose @code{C} is a C@t{++} class, derived from class
@code{Base}, and that the @code{Base} class has a member called
@code{m_size}. Assume a variable @code{c} is has the type of
@@ -23754,21 +23857,25 @@ With the @samp{*} parameter, if a variable object is bound to a
currently running thread, it will not be updated, without any
diagnostic.
-@subsubheading Example
+If @code{-var-set-update-range} was previously used on a varobj, then
+only the selected range of children will be reported.
-@smallexample
-(gdb)
--var-assign var1 3
-^done,value="3"
-(gdb)
--var-update --all-values var1
-^done,changelist=[@{name="var1",value="3",in_scope="true",
-type_changed="false"@}]
-(gdb)
-@end smallexample
+@code{-var-update} reports all the changed varobjs in a tuple named
+@samp{changelist}.
+
+Each item in the change list is itself a tuple holding:
+@table @samp
+@item name
+The name of the varobj.
+
+@item value
+If values were requested for this update, then this field will be
+present and will hold the value of the varobj.
+
+@item in_scope
@anchor{-var-update}
-The field in_scope may take three values:
+This field is a string which may take one of three values:
@table @code
@item "true"
@@ -23790,6 +23897,61 @@ objects.
In the future new values may be added to this list so the front should
be prepared for this possibility. @xref{GDB/MI Development and Front Ends, ,@sc{GDB/MI} Development and Front Ends}.
+@item type_changed
+This is only present if the varobj is still valid. If the type
+changed, then this will be the string @samp{true}; otherwise it will
+be @samp{false}.
+
+@item new_type
+If the varobj's type changed, then this field will be present and will
+hold the new type.
+
+@item new_num_children
+For a dynamic varobj, if the number of children changed, or if the
+type changed, this will be the new number of children.
+
+The @samp{numchild} field in other varobj responses is generally not
+valid for a dynamic varobj -- it will show the number of children that
+@value{GDBN} knows about, but because dynamic varobjs lazily
+instantiate their children, this will not reflect the number of
+children which may be available.
+
+The @samp{new_num_children} attribute only reports changes to the
+number of children known by @value{GDBN}. This is the only way to
+detect whether an update has removed children (which necessarily can
+only happen at the end of the update range).
+
+@item displayhint
+The display hint, if any.
+
+@item has_more
+This is an integer value, which will be 1 if there are more children
+available outside the varobj's update range.
+
+@item dynamic
+This attribute will be present and have the value @samp{1} if the
+varobj is a dynamic varobj. If the varobj is not a dynamic varobj,
+then this attribute will not be present.
+
+@item new_children
+If new children were added to a dynamic varobj within the selected
+update range (as set by @code{-var-set-update-range}), then they will
+be listed in this attribute.
+@end table
+
+@subsubheading Example
+
+@smallexample
+(gdb)
+-var-assign var1 3
+^done,value="3"
+(gdb)
+-var-update --all-values var1
+^done,changelist=[@{name="var1",value="3",in_scope="true",
+type_changed="false"@}]
+(gdb)
+@end smallexample
+
@subheading The @code{-var-set-frozen} Command
@findex -var-set-frozen
@anchor{-var-set-frozen}
@@ -23821,6 +23983,32 @@ Unfreezing a variable does not update it, only subsequent
(gdb)
@end smallexample
+@subheading The @code{-var-set-update-range} command
+@findex -var-set-update-range
+@anchor{-var-set-update-range}
+
+@subsubheading Synopsis
+
+@smallexample
+ -var-set-update-range @var{name} @var{from} @var{to}
+@end smallexample
+
+Set the range of children to be returned by future invocations of
+@code{-var-update}.
+
+@var{from} and @var{to} indicate the range of children to report. If
+@var{from} or @var{to} is less than zero, the range is reset and all
+children will be reported. Otherwise, children starting at @var{from}
+(zero-based) and up to and excluding @var{to} will be reported.
+
+@subsubheading Example
+
+@smallexample
+(gdb)
+-var-set-update-range V 1 2
+^done
+@end smallexample
+
@subheading The @code{-var-set-visualizer} command
@findex -var-set-visualizer
@anchor{-var-set-visualizer}
diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c
index 0cf03d9..ede928c 100644
--- a/gdb/mi/mi-cmd-var.c
+++ b/gdb/mi/mi-cmd-var.c
@@ -41,7 +41,7 @@ static void varobj_update_one (struct varobj *var,
enum print_values print_values,
int explicit);
-static int mi_print_value_p (struct type *type, enum print_values print_values);
+static int mi_print_value_p (struct varobj *var, enum print_values print_values);
/* Print variable object VAR. The PRINT_VALUES parameter controls
if the value should be printed. The PRINT_EXPRESSION parameter
@@ -59,8 +59,12 @@ print_varobj (struct varobj *var, enum print_values print_values,
ui_out_field_string (uiout, "exp", varobj_get_expression (var));
ui_out_field_int (uiout, "numchild", varobj_get_num_children (var));
- if (mi_print_value_p (varobj_get_gdb_type (var), print_values))
- ui_out_field_string (uiout, "value", varobj_get_value (var));
+ if (mi_print_value_p (var, print_values))
+ {
+ char *val = varobj_get_value (var);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
+ }
type = varobj_get_type (var);
if (type != NULL)
@@ -75,6 +79,9 @@ print_varobj (struct varobj *var, enum print_values print_values,
if (varobj_get_frozen (var))
ui_out_field_int (uiout, "frozen", 1);
+
+ if (varobj_pretty_printed_p (var))
+ ui_out_field_int (uiout, "dynamic", 1);
}
/* VAROBJ operations */
@@ -138,6 +145,8 @@ mi_cmd_var_create (char *command, char **argv, int argc)
print_varobj (var, PRINT_ALL_VALUES, 0 /* don't print expression */);
+ ui_out_field_int (uiout, "has_more", varobj_has_more (var, 0));
+
do_cleanups (old_cleanups);
}
@@ -223,6 +232,7 @@ mi_cmd_var_set_format (char *command, char **argv, int argc)
{
enum varobj_display_formats format;
struct varobj *var;
+ char *val;
if (argc != 2)
error (_("mi_cmd_var_set_format: Usage: NAME FORMAT."));
@@ -239,7 +249,9 @@ mi_cmd_var_set_format (char *command, char **argv, int argc)
ui_out_field_string (uiout, "format", varobj_format_string[(int) format]);
/* Report the value in the new format */
- ui_out_field_string (uiout, "value", varobj_get_value (var));
+ val = varobj_get_value (var);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
}
void
@@ -337,11 +349,12 @@ Must be: 0 or \"%s\", 1 or \"%s\", 2 or \"%s\""),
}
/* Return 1 if given the argument PRINT_VALUES we should display
- a value of type TYPE. */
+ the varobj VAR. */
static int
-mi_print_value_p (struct type *type, enum print_values print_values)
+mi_print_value_p (struct varobj *var, enum print_values print_values)
{
+ struct type *type;
if (print_values == PRINT_NO_VALUES)
return 0;
@@ -349,6 +362,10 @@ mi_print_value_p (struct type *type, enum print_values print_values)
if (print_values == PRINT_ALL_VALUES)
return 1;
+ if (varobj_pretty_printed_p (var))
+ return 1;
+
+ type = varobj_get_gdb_type (var);
if (type == NULL)
return 1;
else
@@ -369,24 +386,35 @@ mi_cmd_var_list_children (char *command, char **argv, int argc)
struct varobj *var;
VEC(varobj_p) *children;
struct varobj *child;
- struct cleanup *cleanup_children;
int numchild;
enum print_values print_values;
int ix;
+ int from, to;
char *display_hint;
- if (argc != 1 && argc != 2)
- error (_("mi_cmd_var_list_children: Usage: [PRINT_VALUES] NAME"));
+ if (argc < 1 || argc > 4)
+ error (_("mi_cmd_var_list_children: Usage: [PRINT_VALUES] NAME [FROM TO]"));
/* Get varobj handle, if a valid var obj name was specified */
- if (argc == 1)
+ if (argc == 1 || argc == 3)
var = varobj_get_handle (argv[0]);
else
var = varobj_get_handle (argv[1]);
- children = varobj_list_children (var);
- ui_out_field_int (uiout, "numchild", VEC_length (varobj_p, children));
- if (argc == 2)
+ if (argc > 2)
+ {
+ from = atoi (argv[argc - 2]);
+ to = atoi (argv[argc - 1]);
+ }
+ else
+ {
+ from = -1;
+ to = -1;
+ }
+
+ children = varobj_list_children (var, &from, &to);
+ ui_out_field_int (uiout, "numchild", to - from);
+ if (argc == 2 || argc == 4)
print_values = mi_parse_values_option (argv[0]);
else
print_values = PRINT_NO_VALUES;
@@ -398,21 +426,28 @@ mi_cmd_var_list_children (char *command, char **argv, int argc)
xfree (display_hint);
}
- if (VEC_length (varobj_p, children) == 0)
- return;
-
- if (mi_version (uiout) == 1)
- cleanup_children = make_cleanup_ui_out_tuple_begin_end (uiout, "children");
- else
- cleanup_children = make_cleanup_ui_out_list_begin_end (uiout, "children");
- for (ix = 0; VEC_iterate (varobj_p, children, ix, child); ++ix)
+ if (from < to)
{
- struct cleanup *cleanup_child;
- cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, "child");
- print_varobj (child, print_values, 1 /* print expression */);
- do_cleanups (cleanup_child);
+ struct cleanup *cleanup_children;
+ if (mi_version (uiout) == 1)
+ cleanup_children
+ = make_cleanup_ui_out_tuple_begin_end (uiout, "children");
+ else
+ cleanup_children
+ = make_cleanup_ui_out_list_begin_end (uiout, "children");
+ for (ix = from;
+ ix < to && VEC_iterate (varobj_p, children, ix, child);
+ ++ix)
+ {
+ struct cleanup *cleanup_child;
+ cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, "child");
+ print_varobj (child, print_values, 1 /* print expression */);
+ do_cleanups (cleanup_child);
+ }
+ do_cleanups (cleanup_children);
}
- do_cleanups (cleanup_children);
+
+ ui_out_field_int (uiout, "has_more", varobj_has_more (var, to));
}
void
@@ -538,16 +573,24 @@ mi_cmd_var_evaluate_expression (char *command, char **argv, int argc)
var = varobj_get_handle (argv[optind]);
if (formatFound)
- ui_out_field_string (uiout, "value", varobj_get_formatted_value (var, format));
+ {
+ char *val = varobj_get_formatted_value (var, format);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
+ }
else
- ui_out_field_string (uiout, "value", varobj_get_value (var));
+ {
+ char *val = varobj_get_value (var);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
+ }
}
void
mi_cmd_var_assign (char *command, char **argv, int argc)
{
struct varobj *var;
- char *expression;
+ char *expression, *val;
if (argc != 2)
error (_("mi_cmd_var_assign: Usage: NAME EXPRESSION."));
@@ -563,7 +606,9 @@ mi_cmd_var_assign (char *command, char **argv, int argc)
if (!varobj_set_value (var, expression))
error (_("mi_cmd_var_assign: Could not assign expression to variable object"));
- ui_out_field_string (uiout, "value", varobj_get_value (var));
+ val = varobj_get_value (var);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
}
/* Type used for parameters passing to mi_cmd_var_update_iter. */
@@ -670,6 +715,7 @@ varobj_update_one (struct varobj *var, enum print_values print_values,
for (i = 0; VEC_iterate (varobj_update_result, changes, i, r); ++i)
{
char *display_hint;
+ int from, to;
if (mi_version (uiout) > 1)
cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
@@ -678,8 +724,12 @@ varobj_update_one (struct varobj *var, enum print_values print_values,
switch (r->status)
{
case VAROBJ_IN_SCOPE:
- if (mi_print_value_p (varobj_get_gdb_type (r->varobj), print_values))
- ui_out_field_string (uiout, "value", varobj_get_value (r->varobj));
+ if (mi_print_value_p (r->varobj, print_values))
+ {
+ char *val = varobj_get_value (r->varobj);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
+ }
ui_out_field_string (uiout, "in_scope", "true");
break;
case VAROBJ_NOT_IN_SCOPE:
@@ -699,11 +749,11 @@ varobj_update_one (struct varobj *var, enum print_values print_values,
}
if (r->type_changed)
- {
- ui_out_field_string (uiout, "new_type", varobj_get_type (r->varobj));
- ui_out_field_int (uiout, "new_num_children",
- varobj_get_num_children (r->varobj));
- }
+ ui_out_field_string (uiout, "new_type", varobj_get_type (r->varobj));
+
+ if (r->type_changed || r->children_changed)
+ ui_out_field_int (uiout, "new_num_children",
+ varobj_get_num_children (r->varobj));
display_hint = varobj_get_display_hint (var);
if (display_hint)
@@ -712,28 +762,59 @@ varobj_update_one (struct varobj *var, enum print_values print_values,
xfree (display_hint);
}
- if (r->children_changed)
- {
- int ix;
- struct varobj *child;
- struct cleanup *cleanup =
- make_cleanup_ui_out_list_begin_end (uiout, "children");
+ if (varobj_pretty_printed_p (var))
+ ui_out_field_int (uiout, "dynamic", 1);
- VEC (varobj_p)* children = varobj_list_children (r->varobj);
+ varobj_get_child_range (r->varobj, &from, &to);
+ ui_out_field_int (uiout, "has_more",
+ varobj_has_more (r->varobj, to));
- for (ix = 0; VEC_iterate (varobj_p, children, ix, child); ++ix)
+ if (r->new)
+ {
+ int j;
+ varobj_p child;
+ struct cleanup *cleanup;
+
+ cleanup = make_cleanup_ui_out_list_begin_end (uiout, "new_children");
+ for (j = 0; VEC_iterate (varobj_p, r->new, j, child); ++j)
{
struct cleanup *cleanup_child;
cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
- print_varobj (child, print_values, 1 /* print expression */);
+ print_varobj (child, print_values, 1 /* print_expression */);
do_cleanups (cleanup_child);
}
do_cleanups (cleanup);
+ VEC_free (varobj_p, r->new);
+ r->new = NULL; /* Paranoia. */
}
-
+
if (mi_version (uiout) > 1)
do_cleanups (cleanup);
}
VEC_free (varobj_update_result, changes);
}
+
+void
+mi_cmd_enable_pretty_printing (char *command, char **argv, int argc)
+{
+ if (argc != 0)
+ error (_("mi_cmd_enable_pretty_printing: no arguments allowed"));
+ varobj_enable_pretty_printing ();
+}
+
+void
+mi_cmd_var_set_update_range (char *command, char **argv, int argc)
+{
+ struct varobj *var;
+ int from, to;
+
+ if (argc != 3)
+ error (_("mi_cmd_var_set_update_range: Usage: VAROBJ FROM TO"));
+
+ var = varobj_get_handle (argv[0]);
+ from = atoi (argv[1]);
+ to = atoi (argv[2]);
+
+ varobj_set_child_range (var, from, to);
+}
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index dd3d803..8ba086c 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -52,6 +52,7 @@ struct mi_cmd mi_cmds[] =
{ "data-write-memory", { NULL, 0 }, mi_cmd_data_write_memory},
{ "data-write-register-values", { NULL, 0 }, mi_cmd_data_write_register_values},
{ "enable-timings", { NULL, 0 }, mi_cmd_enable_timings},
+ { "enable-pretty-printing", { NULL, 0 }, mi_cmd_enable_pretty_printing},
{ "environment-cd", { NULL, 0 }, mi_cmd_env_cd},
{ "environment-directory", { NULL, 0 }, mi_cmd_env_dir},
{ "environment-path", { NULL, 0 }, mi_cmd_env_path},
@@ -112,6 +113,7 @@ struct mi_cmd mi_cmds[] =
{ "var-list-children", { NULL, 0 }, mi_cmd_var_list_children},
{ "var-set-format", { NULL, 0 }, mi_cmd_var_set_format},
{ "var-set-frozen", { NULL, 0 }, mi_cmd_var_set_frozen},
+ { "var-set-update-range", { NULL, 0 }, mi_cmd_var_set_update_range },
{ "var-set-visualizer", { NULL, 0 }, mi_cmd_var_set_visualizer},
{ "var-show-attributes", { NULL, 0 }, mi_cmd_var_show_attributes},
{ "var-show-format", { NULL, 0 }, mi_cmd_var_show_format},
diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h
index 85ad0c4..dfab411 100644
--- a/gdb/mi/mi-cmds.h
+++ b/gdb/mi/mi-cmds.h
@@ -99,6 +99,8 @@ extern mi_cmd_argv_ftype mi_cmd_var_set_visualizer;
extern mi_cmd_argv_ftype mi_cmd_var_show_attributes;
extern mi_cmd_argv_ftype mi_cmd_var_show_format;
extern mi_cmd_argv_ftype mi_cmd_var_update;
+extern mi_cmd_argv_ftype mi_cmd_enable_pretty_printing;
+extern mi_cmd_argv_ftype mi_cmd_var_set_update_range;
/* Description of a single command. */
diff --git a/gdb/testsuite/gdb.mi/gdb701.exp b/gdb/testsuite/gdb.mi/gdb701.exp
index d4acdc2..244c731 100644
--- a/gdb/testsuite/gdb.mi/gdb701.exp
+++ b/gdb/testsuite/gdb.mi/gdb701.exp
@@ -54,7 +54,7 @@ mi_gdb_test "-var-list-children fooPtr" \
foreach i [list x y z] {
mi_gdb_test "-var-list-children fooPtr.$i" \
- "(&\".*\"\r\n)*\\^done,numchild=\"0\"" \
+ "(&\".*\"\r\n)*\\^done,numchild=\"0\",has_more=\"0\"" \
"list children of fooPtr.$i"
}
diff --git a/gdb/testsuite/gdb.mi/mi-break.exp b/gdb/testsuite/gdb.mi/mi-break.exp
index 619727d..8d06c0e 100644
--- a/gdb/testsuite/gdb.mi/mi-break.exp
+++ b/gdb/testsuite/gdb.mi/mi-break.exp
@@ -175,7 +175,7 @@ proc test_error {} {
# containing function call, the internal breakpoint created to handle
# function call would be reported, messing up MI output.
mi_gdb_test "-var-create V * return_1()" \
- "\\^done,name=\"V\",numchild=\"0\",value=\"1\",type=\"int\"" \
+ "\\^done,name=\"V\",numchild=\"0\",value=\"1\",type=\"int\",has_more=\"0\"" \
"create varobj for function call"
mi_gdb_test "-var-update *" \
diff --git a/gdb/testsuite/gdb.mi/mi-var-block.exp b/gdb/testsuite/gdb.mi/mi-var-block.exp
index 8806848..93ded26 100644
--- a/gdb/testsuite/gdb.mi/mi-var-block.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-block.exp
@@ -74,7 +74,7 @@ mi_step_to "do_block_tests" "" "var-cmd.c" \
# Test: c_variable-3.4
# Desc: check foo, cb changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"foo\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"cb\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"foo\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"cb\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: cb foo changed"
# step to "foo = 321;"
diff --git a/gdb/testsuite/gdb.mi/mi-var-child.exp b/gdb/testsuite/gdb.mi/mi-var-child.exp
index 1f4bdc6..eb6c456 100644
--- a/gdb/testsuite/gdb.mi/mi-var-child.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-child.exp
@@ -680,7 +680,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.2
# Desc: check that integer changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.integer\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.integer"
# Step over:
@@ -693,7 +693,7 @@ mi_execute_to "exec-step 3" "end-stepping-range" do_children_tests {} ".*${srcfi
# Test: c_variable-5.3
# Desc: check that char_ptr changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.char_ptr"
# Step over "struct_declarations.int_ptr_ptr = &foo;"
@@ -703,7 +703,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.4
# Desc: check that int_ptr_ptr and children changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars int_ptr_ptr and children changed"
# Step over "weird->long_array[0] = 1234;"
@@ -713,7 +713,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.5
# Desc: check that long_array[0] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.0\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.0\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.0 changed"
# Step over "struct_declarations.long_array[1] = 2345;"
@@ -723,7 +723,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.6
# Desc: check that long_array[1] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.1\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.1\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.1 changed"
# Step over "weird->long_array[2] = 3456;"
@@ -733,7 +733,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.7
# Desc: check that long_array[2] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.2\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.2\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.2 changed"
# Step over:
@@ -752,7 +752,7 @@ mi_execute_to "exec-step 7" "end-stepping-range" do_children_tests {} ".*${srcfi
# Test: c_variable-5.8
# Desc: check that long_array[3-9] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.3\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.4\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.5\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.6\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.7\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.8\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.9\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.3\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.4\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.5\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.6\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.7\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.8\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.9\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.3-9 changed"
@@ -763,7 +763,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.9
# Desc: check that func_ptr changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.func_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.func_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.func_ptr changed"
# Step over "struct_declarations.long_array[10] = 3456";
@@ -771,7 +771,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
[expr $line_dct_nothing + 2] "step \$line_dct_nothing + 2"
mi_gdb_test "-var-update --no-values *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.10\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.10\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.10 changed, don't print values."
# Step over "struct_declarations.long_array[11] = 5678";
@@ -780,7 +780,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
$line_dct_a0_0 "step \$line_dct_a0_0"
mi_gdb_test "-var-update --all-values *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.11\",value=\"5678\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.11\",value=\"5678\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.11 changed, print values."
mi_list_varobj_children {struct_declarations.long_array --all-values} {
@@ -1121,7 +1121,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.47
# Desc: check that psnp->char_ptr (and [0].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr.\\*\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr.\\*\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->char_ptr (and 0.char_ptr) changed"
# Step over "snp1.char_ptr = &c3;"
@@ -1131,7 +1131,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.48
# Desc: check that psnp->next->char_ptr (and [1].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr.\\*\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr.\\*\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->char_ptr (and 1.char_ptr) changed"
@@ -1142,7 +1142,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.49
# Desc: check that psnp->next->next->char_ptr (and [2].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->next->char_ptr (and 2.char_ptr) changed"
@@ -1153,7 +1153,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.50
# Desc: check that psnp->long_ptr (and [0].long_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->long_ptr (and 0.long_ptr) changed"
@@ -1181,7 +1181,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.52
# Desc: check that psnp->next->next->long_ptr (and [2].long_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.long_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->next->long_ptr (and 2.long_ptr) changed"
mi_prepare_inline_tests $srcfile
diff --git a/gdb/testsuite/gdb.mi/mi-var-cmd.exp b/gdb/testsuite/gdb.mi/mi-var-cmd.exp
index ad2e55c..6efb333 100644
--- a/gdb/testsuite/gdb.mi/mi-var-cmd.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-cmd.exp
@@ -146,7 +146,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" $line_dlt_linteger "step at do_local
# Test: c_variable-2.2
# Desc: check whether only linteger changed values
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: linteger changed"
# Step over "lpinteger = &linteger;"
@@ -155,7 +155,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 1] "step
# Test: c_variable-2.3
# Desc: check whether only lpinteger changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpinteger changed"
# Step over "lcharacter = 'a';"
@@ -164,7 +164,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 2] "step
# Test: c_variable-2.4
# Desc: check whether only lcharacter changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lcharacter changed"
# Step over "lpcharacter = &lcharacter;"
@@ -173,7 +173,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 3] "step
# Test: c_variable-2.5
# Desc: check whether only lpcharacter changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpcharacter changed"
@@ -195,7 +195,7 @@ mi_execute_to "exec-step 9" "end-stepping-range" "do_locals_tests" "" \
# Desc: check whether llong, lplong, lfloat, lpfloat, ldouble, lpdouble, lsimple.integer,
# lsimple.unsigned_character lsimple.integer lsimple.character changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpdouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lplong\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpdouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lplong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: many changed"
# Step over:
@@ -212,7 +212,7 @@ mi_execute_to "exec-step 4" "end-stepping-range" "do_locals_tests" "" \
# Test: c_variable-2.7
# Desc: check whether (lsimple.signed_character, lsimple.char_ptr) lpsimple, func changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"func\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpsimple\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"func\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpsimple\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: func and lpsimple changed"
# Step over
@@ -234,7 +234,7 @@ mi_execute_to "exec-step 8" "end-stepping-range" "do_locals_tests" "" \
# Note: this test also checks that lpsimple->integer and lsimple.integer have
# changed (they are the same)
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lsimple and others changed"
@@ -257,7 +257,7 @@ mi_gdb_test "-var-assign linteger 3333" \
# change.
set lpchar_update "\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\},"
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[($lpchar_update)?\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[($lpchar_update)?\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: linteger changed after assign"
mi_gdb_test "-var-assign linteger 3333" \
@@ -277,7 +277,7 @@ mi_gdb_test "-var-assign lpinteger \"&linteger + 3\"" \
"assign to lpinteger"
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpinteger changed after assign"
mi_gdb_test "-var-update *" \
@@ -377,7 +377,7 @@ mi_gdb_test "-var-update *" \
"assign same value to func (update)"
mi_gdb_test "-var-create array_ptr * array_ptr" \
- "\\^done,name=\"array_ptr\",numchild=\"1\",value=\"$hex\",type=\"int \\*\"" \
+ "\\^done,name=\"array_ptr\",numchild=\"1\",value=\"$hex\",type=\"int \\*\",has_more=\"0\"" \
"create global variable array_ptr"
mi_gdb_test "-var-assign array_ptr array2" \
@@ -385,7 +385,7 @@ mi_gdb_test "-var-assign array_ptr array2" \
"assign array to pointer"
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"array_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"array_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"assign array to pointer (update)"
mi_gdb_test "-var-assign array_ptr array2" \
@@ -439,7 +439,7 @@ mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\
# Test: c_variable-2.13
# Desc: change subroutine1 local i
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"i\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"i\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: i changed"
mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\}" \
@@ -448,7 +448,7 @@ mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\
# Test: c_variable-2.14
# Desc: change do_locals_tests local llong
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: llong changed"
set line_dlt_call_subroutine1 [gdb_get_line_number "subroutine1 (linteger, &llong);"]
@@ -458,7 +458,7 @@ mi_next_to "do_locals_tests" "" "var-cmd.c" \
# Test: c_variable-2.15
# Desc: check for out of scope subroutine1 locals
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\,type_changed=\"false\"},\{name=\"i\",in_scope=\"false\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\,type_changed=\"false\",has_more=\"0\"},\{name=\"i\",in_scope=\"false\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: all now out of scope"
# Done with locals/globals tests. Erase all variables
@@ -550,14 +550,14 @@ mi_gdb_test "-var-create selected_a @ a" \
mi_continue_to incr_a
mi_gdb_test "-var-update selected_a" \
- "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"char\",new_num_children=\"0\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"char\",new_num_children=\"0\",has_more=\"0\"\}\\\]" \
"update selected_a in incr_a"
mi_next "step a line in incr_a"
mi_next "return from incr_a to do_special_tests"
mi_gdb_test "-var-update selected_a" \
- "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"int\",new_num_children=\"0\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"int\",new_num_children=\"0\",has_more=\"0\"\}\\\]" \
"update selected_a in do_special_tests"
mi_gdb_test "-file-exec-and-symbols ${binfile}" "\\^done" \
@@ -596,7 +596,7 @@ mi_check_varobj_value F 7 "check F inside callee"
# A varobj we fail to read during -var-update should be considered
# out of scope.
mi_gdb_test "-var-create null_ptr * **0" \
- {\^done,name="null_ptr",numchild="0",value=".*",type="int"} \
+ {\^done,name="null_ptr",numchild="0",value=".*",type="int",has_more="0"} \
"create null_ptr"
# Allow this to succeed, if address zero is readable, although it
@@ -644,7 +644,7 @@ mi_check_varobj_value "L" "{...}" "in-and-out-of-scope: check initial value"
mi_runto main
mi_gdb_test "-var-update L" \
- {\^done,changelist=\[{name="L",in_scope="false",type_changed="false"}\]} \
+ {\^done,changelist=\[{name="L",in_scope="false",type_changed="false",has_more="0"}\]} \
"in-and-out-of-scope: out of scope now"
mi_gdb_test "-var-update L" \
@@ -654,7 +654,7 @@ mi_gdb_test "-var-update L" \
mi_continue_to do_locals_tests
mi_gdb_test "-var-update L" \
- {\^done,changelist=\[{name="L",in_scope="true",type_changed="false"}\]} \
+ {\^done,changelist=\[{name="L",in_scope="true",type_changed="false",has_more="0"}\]} \
"in-and-out-of-scope: in scope now"
mi_gdb_test "-var-update L" \
diff --git a/gdb/testsuite/gdb.mi/mi-var-display.exp b/gdb/testsuite/gdb.mi/mi-var-display.exp
index 4b02e50..faa9172 100644
--- a/gdb/testsuite/gdb.mi/mi-var-display.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-display.exp
@@ -558,7 +558,7 @@ mi_gdb_test "-var-info-num-children e" \
# Test: c_variable-7.55
# Desc: children of e
mi_gdb_test "-var-list-children e" \
- "\\^done,numchild=\"0\"" \
+ "\\^done,numchild=\"0\",has_more=\"0\"" \
"get children of e"
# Test: c_variable-7.60
@@ -600,7 +600,7 @@ mi_gdb_test "-var-info-num-children anone" \
# Test: c_variable-7.75
# Desc: children of anone
mi_gdb_test "-var-list-children anone" \
- "\\^done,numchild=\"0\"" \
+ "\\^done,numchild=\"0\",has_more=\"0\"" \
"get children of anone"
diff --git a/gdb/testsuite/gdb.mi/mi-var-invalidate.exp b/gdb/testsuite/gdb.mi/mi-var-invalidate.exp
index 05d46fa..4b95674 100644
--- a/gdb/testsuite/gdb.mi/mi-var-invalidate.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-invalidate.exp
@@ -72,7 +72,7 @@ mi_runto main
# Check local variable is "invalid".
mi_gdb_test "-var-update linteger" \
- "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"invalid\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"invalid\",has_more=\"0\"\}\\\]" \
"linteger not anymore in scope due to binary changes"
mi_gdb_test "-var-info-type linteger" \
@@ -97,7 +97,7 @@ mi_delete_breakpoints
mi_gdb_load ${binfile2}
# Check local variable are "invalid"
mi_gdb_test "-var-update linteger" \
- "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"invalid\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"invalid\",has_more=\"0\"\}\\\]" \
"linteger not valid anymore due to binary changes"
mi_gdb_test "-var-info-type linteger" \
@@ -106,7 +106,7 @@ mi_gdb_test "-var-info-type linteger" \
# Check global variable are still correct.
mi_gdb_test "-var-update global_simple" \
- "\\^done,changelist=\\\[\{name=\"global_simple\",in_scope=\"invalid\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"global_simple\",in_scope=\"invalid\",has_more=\"0\"\}\\\]" \
"global_simple not anymore in scope due to binary changes"
mi_gdb_test "-var-info-type global_simple" \
diff --git a/gdb/testsuite/gdb.mi/mi2-var-block.exp b/gdb/testsuite/gdb.mi/mi2-var-block.exp
index 6bcfea3..9b3d08f 100644
--- a/gdb/testsuite/gdb.mi/mi2-var-block.exp
+++ b/gdb/testsuite/gdb.mi/mi2-var-block.exp
@@ -74,7 +74,7 @@ mi_step_to "do_block_tests" "" "var-cmd.c" \
# Test: c_variable-3.4
# Desc: check foo, cb changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"foo\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"cb\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"foo\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"cb\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: cb foo changed"
# step to "foo = 321;"
diff --git a/gdb/testsuite/gdb.mi/mi2-var-child.exp b/gdb/testsuite/gdb.mi/mi2-var-child.exp
index 161b34f..0f9b4d4 100644
--- a/gdb/testsuite/gdb.mi/mi2-var-child.exp
+++ b/gdb/testsuite/gdb.mi/mi2-var-child.exp
@@ -1,4 +1,4 @@
-# Copyright 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
+# Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2009 Free Software Foundation
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -680,7 +680,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.2
# Desc: check that integer changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.integer\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.integer"
# Step over:
@@ -693,7 +693,7 @@ mi_execute_to "exec-step 3" "end-stepping-range" do_children_tests {} {.*var-cmd
# Test: c_variable-5.3
# Desc: check that char_ptr changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.char_ptr"
# Step over "struct_declarations.int_ptr_ptr = &foo;"
@@ -703,7 +703,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.4
# Desc: check that int_ptr_ptr and children changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars int_ptr_ptr and children changed"
# Step over "weird->long_array[0] = 1234;"
@@ -713,7 +713,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.5
# Desc: check that long_array[0] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.0\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.0\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.0 changed"
# Step over "struct_declarations.long_array[1] = 2345;"
@@ -723,7 +723,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.6
# Desc: check that long_array[1] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.1\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.1\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.1 changed"
# Step over "weird->long_array[2] = 3456;"
@@ -733,7 +733,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.7
# Desc: check that long_array[2] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.2\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.2\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.2 changed"
# Step over:
@@ -752,7 +752,7 @@ mi_execute_to "exec-step 7" "end-stepping-range" do_children_tests {} {.*var-cmd
# Test: c_variable-5.8
# Desc: check that long_array[3-9] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.3\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.4\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.5\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.6\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.7\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.8\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.9\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.3\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.4\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.5\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.6\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.7\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.8\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.9\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.3-9 changed"
@@ -764,7 +764,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.9
# Desc: check that func_ptr changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.func_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.func_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.func_ptr changed"
# Delete all variables
@@ -1075,7 +1075,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.47
# Desc: check that psnp->char_ptr (and [0].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr.\\*\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr.\\*\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->char_ptr (and 0.char_ptr) changed"
# Step over "snp1.char_ptr = &c3;"
@@ -1085,7 +1085,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.48
# Desc: check that psnp->next->char_ptr (and [1].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr.\\*\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr.\\*\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->char_ptr (and 1.char_ptr) changed"
@@ -1096,7 +1096,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.49
# Desc: check that psnp->next->next->char_ptr (and [2].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->next->char_ptr (and 2.char_ptr) changed"
@@ -1107,7 +1107,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.50
# Desc: check that psnp->long_ptr (and [0].long_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->long_ptr (and 0.long_ptr) changed"
@@ -1120,7 +1120,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Why does this have a FIXME?
setup_xfail *-*-*
mi_gdb_test "-var-update *" \
- "FIXME\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.long_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "FIXME\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->long_ptr (and 1.long_ptr) changed"
clear_xfail *-*-*
@@ -1135,7 +1135,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.52
# Desc: check that psnp->next->next->long_ptr (and [2].long_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.long_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->next->long_ptr (and 2.long_ptr) changed"
diff --git a/gdb/testsuite/gdb.mi/mi2-var-cmd.exp b/gdb/testsuite/gdb.mi/mi2-var-cmd.exp
index dda77bb..e900d14 100644
--- a/gdb/testsuite/gdb.mi/mi2-var-cmd.exp
+++ b/gdb/testsuite/gdb.mi/mi2-var-cmd.exp
@@ -126,11 +126,6 @@ mi_gdb_test "-var-create int * int" \
"&\"Attempt to use a type name as an expression.\\\\n\".*\\^error,msg=\"mi_cmd_var_create: unable to create variable object\"" \
"create int"
-# The number 0 must be an invalid frame address and linteger a local variable.
-mi_gdb_test "-var-create invalidframe 0 linteger" \
- "\\^error,msg=\"Failed to find the specified frame\"" \
- "create variable with invalid FRAME-ADDR"
-
##### #####
# #
@@ -151,7 +146,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" $line_dlt_linteger "step at do_local
# Test: c_variable-2.2
# Desc: check whether only linteger changed values
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: linteger changed"
# Step over "lpinteger = &linteger;"
@@ -160,7 +155,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 1] "step
# Test: c_variable-2.3
# Desc: check whether only lpinteger changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpinteger changed"
# Step over "lcharacter = 'a';"
@@ -169,7 +164,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 2] "step
# Test: c_variable-2.4
# Desc: check whether only lcharacter changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lcharacter changed"
# Step over "lpcharacter = &lcharacter;"
@@ -178,7 +173,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 3] "step
# Test: c_variable-2.5
# Desc: check whether only lpcharacter changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpcharacter changed"
@@ -200,7 +195,7 @@ mi_execute_to "exec-step 9" "end-stepping-range" "do_locals_tests" "" \
# Desc: check whether llong, lplong, lfloat, lpfloat, ldouble, lpdouble, lsimple.integer,
# lsimple.unsigned_character lsimple.integer lsimple.character changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpdouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lplong\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpdouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lplong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: many changed"
# Step over:
@@ -217,7 +212,7 @@ mi_execute_to "exec-step 4" "end-stepping-range" "do_locals_tests" "" \
# Test: c_variable-2.7
# Desc: check whether (lsimple.signed_character, lsimple.char_ptr) lpsimple, func changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"func\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpsimple\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"func\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpsimple\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: func and lpsimple changed"
# Step over
@@ -239,7 +234,7 @@ mi_execute_to "exec-step 8" "end-stepping-range" "do_locals_tests" "" \
# Note: this test also checks that lpsimple->integer and lsimple.integer have
# changed (they are the same)
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lsimple and others changed"
@@ -262,7 +257,7 @@ mi_gdb_test "-var-assign linteger 3333" \
# change.
set lpchar_update "\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\},"
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[($lpchar_update)?\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[($lpchar_update)?\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: linteger changed after assign"
mi_gdb_test "-var-assign linteger 3333" \
@@ -282,7 +277,7 @@ mi_gdb_test "-var-assign lpinteger \"&linteger + 3\"" \
"assign to lpinteger"
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpinteger changed after assign"
mi_gdb_test "-var-update *" \
@@ -407,7 +402,7 @@ mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\
# Test: c_variable-2.13
# Desc: change subroutine1 local i
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"i\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"i\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: i changed"
mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\}" \
@@ -416,7 +411,7 @@ mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\
# Test: c_variable-2.14
# Desc: change do_locals_tests local llong
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: llong changed"
set line_dlt_call_subroutine1 [gdb_get_line_number "subroutine1 (linteger, &llong);"]
@@ -426,7 +421,7 @@ mi_next_to "do_locals_tests" "" "var-cmd.c" \
# Test: c_variable-2.15
# Desc: check for out of scope subroutine1 locals
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\,type_changed=\"false\"},\{name=\"i\",in_scope=\"false\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\,type_changed=\"false\",has_more=\"0\"},\{name=\"i\",in_scope=\"false\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: all now out of scope"
# Done with locals/globals tests. Erase all variables
@@ -518,14 +513,14 @@ mi_gdb_test "-var-create selected_a @ a" \
mi_continue_to incr_a
mi_gdb_test "-var-update selected_a" \
- "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"char\",new_num_children=\"0\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"char\",new_num_children=\"0\"\,has_more=\"0\"}\\\]" \
"update selected_a in incr_a"
mi_next "step a line in incr_a"
mi_next "return from incr_a to do_special_tests"
mi_gdb_test "-var-update selected_a" \
- "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"int\",new_num_children=\"0\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"int\",new_num_children=\"0\",has_more=\"0\"\}\\\]" \
"update selected_a in do_special_tests"
mi_gdb_test "-file-exec-and-symbols ${binfile}" "\\^done" \
diff --git a/gdb/testsuite/gdb.mi/mi2-var-display.exp b/gdb/testsuite/gdb.mi/mi2-var-display.exp
index d6ce673..17e208a 100644
--- a/gdb/testsuite/gdb.mi/mi2-var-display.exp
+++ b/gdb/testsuite/gdb.mi/mi2-var-display.exp
@@ -557,7 +557,7 @@ mi_gdb_test "-var-info-num-children e" \
# Test: c_variable-7.55
# Desc: children of e
mi_gdb_test "-var-list-children e" \
- "\\^done,numchild=\"0\"" \
+ "\\^done,numchild=\"0\",has_more=\"0\"" \
"get children of e"
# Test: c_variable-7.60
@@ -599,7 +599,7 @@ mi_gdb_test "-var-info-num-children anone" \
# Test: c_variable-7.75
# Desc: children of anone
mi_gdb_test "-var-list-children anone" \
- "\\^done,numchild=\"0\"" \
+ "\\^done,numchild=\"0\",has_more=\"0\"" \
"get children of anone"
diff --git a/gdb/testsuite/gdb.python/py-mi.exp b/gdb/testsuite/gdb.python/py-mi.exp
index d3f44b2..30d6f32 100644
--- a/gdb/testsuite/gdb.python/py-mi.exp
+++ b/gdb/testsuite/gdb.python/py-mi.exp
@@ -48,23 +48,53 @@ mi_gdb_test "python execfile ('${srcdir}/${subdir}/${testfile}.py')" ""
mi_continue_to_line [gdb_get_line_number {MI breakpoint here} ${testfile}.c] \
"step to breakpoint"
-mi_create_floating_varobj container c "create container varobj"
+mi_create_dynamic_varobj container c \
+ "create container varobj, no pretty-printing"
+
+mi_list_varobj_children container {
+ { container.name name 1 string }
+ { container.len len 0 int }
+ { container.elements elements 1 "int ." }
+} "examine container children=0, no pretty-printing"
+
+mi_delete_varobj container "delete varobj"
+
+mi_gdb_test "-enable-pretty-printing" ""
+
+mi_create_varobj_checked string string_1 \
+ "struct string_repr" \
+ "create string_1 varobj"
+
+mi_gdb_test "-data-evaluate-expression \"string_1 = string_2\"" ".*" \
+ "assign string_1 from string_2"
+
+mi_gdb_test "-var-update string" \
+ "\\^done,changelist=\\\[{name=\"string\",in_scope=\"true\",type_changed=\"false\",dynamic=\"1\",has_more=\"0\"}\\\]" \
+ "update string varobj after assignment"
+
+mi_create_dynamic_varobj container c \
+ "create container varobj"
mi_list_varobj_children container {
} "examine container children=0"
mi_next "next over update 1"
-mi_varobj_update_dynamic container {
- { {container.\[0\]} {\[0\]} 0 int }
-} "varobj update 1"
+mi_varobj_update_dynamic container "varobj update 1" {
+ type_changed false new_num_children 1 dynamic 1 has_more 0
+} {
+} {
+ { name {container.\[0\]} exp {\[0\]} numchild 0 type int thread-id 1 }
+}
mi_next "next over update 2"
-mi_varobj_update_dynamic container {
- { {container.\[0\]} {\[0\]} 0 int }
- { {container.\[1\]} {\[1\]} 0 int }
-} "varobj update 2"
+mi_varobj_update_dynamic container "varobj update 2" {
+ type_changed false new_num_children 2 dynamic 1 has_more 0
+} {
+} {
+ { name {container.\[1\]} exp {\[1\]} numchild 0 type int thread-id 1 }
+}
mi_gdb_test "-var-set-visualizer container None" \
"\\^done" \
@@ -78,19 +108,124 @@ mi_gdb_test "-var-set-visualizer container gdb.default_visualizer" \
"\\^done" \
"choose default visualizer"
-mi_varobj_update_dynamic container {
- { {container.\[0\]} {\[0\]} 0 int }
- { {container.\[1\]} {\[1\]} 0 int }
-} "varobj update after choosing default"
+mi_varobj_update_dynamic container "varobj update after choosing default" {
+ type_changed false new_num_children 2 dynamic 1 has_more 0
+} {
+} {
+ { name {container.\[0\]} exp {\[0\]} numchild 0 type int thread-id 1 }
+ { name {container.\[1\]} exp {\[1\]} numchild 0 type int thread-id 1 }
+}
mi_gdb_test "-var-set-visualizer container ContainerPrinter" \
"\\^done" \
"choose visualizer using expression"
-mi_varobj_update_dynamic container {
+mi_varobj_update_dynamic container \
+ "varobj update after choosing via expression" {
+ type_changed false new_num_children 2 dynamic 1 has_more 0
+ } {
+ } {
+ { name {container.\[0\]} exp {\[0\]} numchild 0 type int thread-id 1 }
+ { name {container.\[1\]} exp {\[1\]} numchild 0 type int thread-id 1 }
+ }
+
+mi_list_varobj_children_range container 1 2 2 {
+ { {container.\[1\]} {\[1\]} 0 int }
+} "list varobj children after selecting child range"
+
+mi_list_varobj_children_range container -1 -1 2 {
{ {container.\[0\]} {\[0\]} 0 int }
{ {container.\[1\]} {\[1\]} 0 int }
-} "varobj update after choosing via expression"
+} "list varobj children after resetting child range"
+
+mi_next "next over update 3"
+
+mi_gdb_test "-var-set-update-range container 0 1" \
+ "\\^done" \
+ "set update range"
+
+# This should truncate the list.
+mi_list_varobj_children container {
+ { {container.\[0\]} {\[0\]} 0 int }
+} "list children after setting update range"
+
+# This should return just the items in [1,2).
+mi_list_varobj_children_range container 1 2 2 {
+ { {container.\[1\]} {\[1\]} 0 int }
+} "list selected children after setting range"
+
+# This should not be affected by the previous list-children request.
+mi_list_varobj_children container {
+ { {container.\[0\]} {\[0\]} 0 int }
+} "list children after listing selected range"
+
+mi_next "next over update 4"
+
+# This should only show the first child, because the update range has
+# been set.
+mi_varobj_update_dynamic container \
+ "update after next with restricted range" {
+ type_changed false new_num_children 1 dynamic 1 has_more 1
+ } {
+ { name {container.\[0\]} in_scope true type_changed false dynamic 1 has_more 0 }
+ } {
+ }
+
+mi_gdb_test "-var-set-update-range container 3 4" \
+ "\\^done" \
+ "set update range with non-zero start"
+
+# Elements were updated but should not be reported.
+mi_varobj_update_dynamic container \
+ "update varobj with change outside selected range" {
+ type_changed false new_num_children 3 dynamic 1 has_more 0
+ } {
+ } {
+ }
+
+mi_next "next over update 5"
+
+# Regression test: examine an object that has no children, then update
+# it to ensure that we don't print the children.
+mi_create_dynamic_varobj container2 c2 \
+ "create second container varobj"
+
+mi_gdb_test "-var-update container2" \
+ "\\^done,changelist=.." \
+ "update varobj, no children requested"
+
+mi_next "next over update 6"
+
+# Now container2 has an element -- and an update should mention that
+# it has_more. But, because we did not request children, we still
+# should not actually see them.
+mi_varobj_update_dynamic container2 \
+ "update varobj 2, no children requested" {
+ type_changed false dynamic 1 has_more 1
+ } {} {}
+
+mi_continue_to_line \
+ [gdb_get_line_number {MI outer breakpoint here} ${testfile}.c] \
+ "step to outer breakpoint"
+
+mi_create_dynamic_varobj outer outer \
+ "create outer varobj"
+
+mi_list_varobj_children outer {
+ { outer.s s 2 "struct substruct" }
+ { outer.x x 0 "int" }
+} "list children of outer"
+
+mi_list_varobj_children outer.s {
+ { outer.s.a a 0 int }
+ { outer.s.b b 0 int }
+} "list children of outer.s"
+
+mi_next "next over outer update"
+
+mi_gdb_test "-var-update outer" \
+ ".done,changelist=.{name=\"outer.s.a\",in_scope=\"true\",type_changed=\"false\",dynamic=\"1\",has_more=\"0\"}." \
+ "update after updating element of outer"
mi_continue_to_line \
[gdb_get_line_number {Another MI breakpoint} ${testfile}.c] \
diff --git a/gdb/testsuite/gdb.python/py-prettyprint.c b/gdb/testsuite/gdb.python/py-prettyprint.c
index 3cafc48..7f16400 100644
--- a/gdb/testsuite/gdb.python/py-prettyprint.c
+++ b/gdb/testsuite/gdb.python/py-prettyprint.c
@@ -15,6 +15,8 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
+#include <string.h>
+
struct s
{
int a;
@@ -80,6 +82,29 @@ class Derived : public Vbase1, public Vbase2, public Vbase3
#endif
+struct substruct {
+ int a;
+ int b;
+};
+
+struct outerstruct {
+ struct substruct s;
+ int x;
+};
+
+struct outerstruct
+substruct_test (void)
+{
+ struct outerstruct outer;
+ outer.s.a = 0;
+ outer.s.b = 0;
+ outer.x = 0;
+
+ outer.s.a = 3; /* MI outer breakpoint here */
+
+ return outer;
+}
+
typedef struct string_repr
{
struct whybother
@@ -148,6 +173,14 @@ void do_nothing(void)
c = 23; /* Another MI breakpoint */
}
+struct nullstr
+{
+ char *s;
+};
+
+struct string_repr string_1 = { { "one" } };
+struct string_repr string_2 = { { "two" } };
+
int
main ()
{
@@ -155,11 +188,15 @@ main ()
struct ss ssa[2];
string x = make_string ("this is x");
zzz_type c = make_container ("container");
+ zzz_type c2 = make_container ("container2");
const struct string_repr cstring = { { "const string" } };
+ /* Clearing by being `static' could invoke an other GDB C++ bug. */
+ struct nullstr nullstr;
init_ss(&ss, 1, 2);
init_ss(ssa+0, 3, 4);
init_ss(ssa+1, 5, 6);
+ memset (&nullstr, 0, sizeof nullstr);
struct ns ns;
ns.null_str = "embedded\0null\0string";
@@ -193,6 +230,14 @@ main ()
add_item (&c, 72);
#ifdef MI
+ add_item (&c, 1011);
+ c.elements[0] = 1023;
+ c.elements[0] = 2323;
+
+ add_item (&c2, 2222);
+ add_item (&c2, 3333);
+
+ substruct_test ();
do_nothing ();
#endif
diff --git a/gdb/testsuite/gdb.python/py-prettyprint.py b/gdb/testsuite/gdb.python/py-prettyprint.py
index bf009a1..2f070d8 100644
--- a/gdb/testsuite/gdb.python/py-prettyprint.py
+++ b/gdb/testsuite/gdb.python/py-prettyprint.py
@@ -92,6 +92,13 @@ class pp_vbase1:
def to_string (self):
return "pp class name: " + self.val.type.tag
+class pp_nullstr:
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ return self.val['s'].string(gdb.parameter('target-charset'))
+
class pp_ns:
"Print a std::basic_string of some kind"
@@ -105,11 +112,24 @@ class pp_ns:
def display_hint (self):
return 'string'
+class pp_outer:
+ "Print struct outer"
+
+ def __init__ (self, val):
+ self.val = val
+
+ def to_string (self):
+ return "x = %s" % self.val['x']
+
+ def children (self):
+ yield 's', self.val['s']
+ yield 'x', self.val['x']
+
def lookup_function (val):
"Look-up and return a pretty-printer that can print val."
# Get the type.
- type = val.type;
+ type = val.type
# If it points to a reference, get the reference.
if type.code == gdb.TYPE_CODE_REF:
@@ -148,6 +168,9 @@ def register_pretty_printers ():
pretty_printers_dict[re.compile ('^VirtualTest$')] = pp_multiple_virtual
pretty_printers_dict[re.compile ('^Vbase1$')] = pp_vbase1
+
+ pretty_printers_dict[re.compile ('^struct nullstr$')] = pp_nullstr
+ pretty_printers_dict[re.compile ('^nullstr$')] = pp_nullstr
# Note that we purposely omit the typedef names here.
# Printer lookup is based on canonical name.
@@ -160,6 +183,10 @@ def register_pretty_printers ():
pretty_printers_dict[re.compile ('^struct ns$')] = pp_ns
pretty_printers_dict[re.compile ('^ns$')] = pp_ns
+
+ pretty_printers_dict[re.compile ('^struct outerstruct$')] = pp_outer
+ pretty_printers_dict[re.compile ('^outerstruct$')] = pp_outer
+
pretty_printers_dict = {}
register_pretty_printers ()
diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
index e691232..167a02c 100644
--- a/gdb/testsuite/lib/mi-support.exp
+++ b/gdb/testsuite/lib/mi-support.exp
@@ -1195,13 +1195,13 @@ proc mi_list_breakpoints { expected test } {
# Name cannot be "-".
proc mi_create_varobj { name expression testname } {
mi_gdb_test "-var-create $name * $expression" \
- "\\^done,name=\"$name\",numchild=\"\[0-9\]+\",value=\".*\",type=.*" \
+ "\\^done,name=\"$name\",numchild=\"\[0-9\]+\",value=\".*\",type=.*,has_more=\"0\"" \
$testname
}
proc mi_create_floating_varobj { name expression testname } {
mi_gdb_test "-var-create $name @ $expression" \
- "\\^done,name=\"$name\",numchild=\"\[0-9\]+\",value=\".*\",type=.*" \
+ "\\^done,name=\"$name\",numchild=\"\(-1\|\[0-9\]+\)\",value=\".*\",type=.*" \
$testname
}
@@ -1214,6 +1214,14 @@ proc mi_create_varobj_checked { name expression type testname } {
$testname
}
+# Same as mi_create_floating_varobj, but assumes the test is creating
+# a dynamic varobj that has children, so the value must be "{...}".
+proc mi_create_dynamic_varobj {name expression testname} {
+ mi_gdb_test "-var-create $name @ $expression" \
+ "\\^done,name=\"$name\",numchild=\"\(-1\|\[0-9\]+\)\",value=\"{\\.\\.\\.}\",type=.*" \
+ $testname
+}
+
# Deletes the specified NAME.
proc mi_delete_varobj { name testname } {
mi_gdb_test "-var-delete $name" \
@@ -1229,7 +1237,7 @@ proc mi_varobj_update { name expected testname } {
set er "\\^done,changelist=\\\["
set first 1
foreach item $expected {
- set v "{name=\"$item\",in_scope=\"true\",type_changed=\"false\"}"
+ set v "{name=\"$item\",in_scope=\"true\",type_changed=\"false\",has_more=\".\"}"
if {$first == 1} {
set er "$er$v"
set first 0
@@ -1244,22 +1252,70 @@ proc mi_varobj_update { name expected testname } {
}
proc mi_varobj_update_with_type_change { name new_type new_children testname } {
- set v "{name=\"$name\",in_scope=\"true\",type_changed=\"true\",new_type=\"$new_type\",new_num_children=\"$new_children\"}"
+ set v "{name=\"$name\",in_scope=\"true\",type_changed=\"true\",new_type=\"$new_type\",new_num_children=\"$new_children\",has_more=\".\"}"
set er "\\^done,changelist=\\\[$v\\\]"
verbose -log "Expecting: $er"
mi_gdb_test "-var-update $name" $er $testname
}
-# Update a dynamic varobj named NAME. CHILDREN is a list of children,
-# in the same form as mi_list_varobj_children. TESTNAME is the name
-# of the test.
-proc mi_varobj_update_dynamic {name children testname} {
- set children_exp_j [mi_child_regexp $children 0]
+# A helper that turns a key/value list into a regular expression
+# matching some MI output.
+proc mi_varobj_update_kv_helper {list} {
+ set first 1
+ set rx ""
+ foreach {key value} $list {
+ if {!$first} {
+ append rx ,
+ }
+ set first 0
+ if {$key == "new_children"} {
+ append rx "$key=\\\[$value\\\]"
+ } else {
+ append rx "$key=\"$value\""
+ }
+ }
+ return $rx
+}
- set er "\\^done,changelist=\\\["
+# A helper for mi_varobj_update_dynamic that computes a match
+# expression given a child list.
+proc mi_varobj_update_dynamic_helper {children} {
+ set crx ""
- append er "{name=\"$name\",in_scope=\"true\",type_changed=\"false\""
- append er ",children=\\\[$children_exp_j.*\\\]}\\\]"
+ set first 1
+ foreach child $children {
+ if {!$first} {
+ append crx ,
+ }
+ set first 0
+ append crx "{"
+ append crx [mi_varobj_update_kv_helper $child]
+ append crx "}"
+ }
+
+ return $crx
+}
+
+# Update a dynamic varobj named NAME. CHILDREN is a list of children
+# that have been updated; NEW_CHILDREN is a list of children that were
+# added to the primary varobj. Each child is a list of key/value
+# pairs that are expected. SELF is a key/value list holding
+# information about the varobj itself. TESTNAME is the name of the
+# test.
+proc mi_varobj_update_dynamic {name testname self children new_children} {
+ if {[llength $new_children]} {
+ set newrx [mi_varobj_update_dynamic_helper $new_children]
+ lappend self new_children $newrx
+ }
+ set selfrx [mi_varobj_update_kv_helper $self]
+ set crx [mi_varobj_update_dynamic_helper $children]
+
+ set er "\\^done,changelist=\\\[\{name=\"$name\",in_scope=\"true\""
+ append er ",$selfrx\}"
+ if {"$crx" != ""} {
+ append er ",$crx"
+ }
+ append er "\\\]"
verbose -log "Expecting: $er"
mi_gdb_test "-var-update $name" $er $testname
@@ -1329,14 +1385,13 @@ proc mi_child_regexp {children add_child} {
# have no value.
#
proc mi_list_varobj_children { varname children testname } {
- mi_list_varobj_children_range $varname [llength $children] $children \
+ mi_list_varobj_children_range $varname "" "" [llength $children] $children \
$testname
}
-# Like mi_list_varobj_children, but assumes that a subrange has been
-# selected with -var-set-child-range. NUMCHILDREN is the total number
-# of children.
-proc mi_list_varobj_children_range {varname numchildren children testname} {
+# Like mi_list_varobj_children, but sets a subrange. NUMCHILDREN is
+# the total number of children.
+proc mi_list_varobj_children_range {varname from to numchildren children testname} {
set options ""
if {[llength $varname] == 2} {
set options [lindex $varname 1]
@@ -1352,9 +1407,18 @@ proc mi_list_varobj_children_range {varname numchildren children testname} {
set expected "\\^done,numchild=\"0\""
}
+ if {"$to" == ""} {
+ append expected ",has_more=\"0\""
+ } elseif {$to >= 0 && $numchildren > $to} {
+ append expected ",has_more=\"1\""
+ } else {
+ append expected ",has_more=\"0\""
+ }
+
verbose -log "Expecting: $expected"
- mi_gdb_test "-var-list-children $options $varname" $expected $testname
+ mi_gdb_test "-var-list-children $options $varname $from $to" \
+ $expected $testname
}
# Verifies that variable object VARNAME has NUMBER children,
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 603071f..e7fb589 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -29,6 +29,7 @@
#include "gdb_assert.h"
#include "gdb_string.h"
+#include "gdb_regex.h"
#include "varobj.h"
#include "vec.h"
@@ -59,6 +60,15 @@ char *varobj_format_string[] =
/* String representations of gdb's known languages */
char *varobj_language_string[] = { "unknown", "C", "C++", "Java" };
+/* True if we want to allow Python-based pretty-printing. */
+static int pretty_printing = 0;
+
+void
+varobj_enable_pretty_printing (void)
+{
+ pretty_printing = 1;
+}
+
/* Data structures */
/* Every root variable has one of these structures saved in its
@@ -173,9 +183,31 @@ struct varobj
frozen. */
int not_fetched;
+ /* Sub-range of children which the MI consumer has requested. If
+ FROM < 0 or TO < 0, means that all children have been
+ requested. */
+ int from;
+ int to;
+
+ /* The pretty-printer constructor. If NULL, then the default
+ pretty-printer will be looked up. If None, then no
+ pretty-printer will be installed. */
+ PyObject *constructor;
+
/* The pretty-printer that has been constructed. If NULL, then a
new printer object is needed, and one will be constructed. */
PyObject *pretty_printer;
+
+ /* The iterator returned by the printer's 'children' method, or NULL
+ if not available. */
+ PyObject *child_iter;
+
+ /* We request one extra item from the iterator, so that we can
+ report to the caller whether there are more items than we have
+ already reported. However, we don't want to install this value
+ when we read it, because that will mess up future updates. So,
+ we stash it here instead. */
+ PyObject *saved_item;
};
struct cpstack
@@ -236,8 +268,6 @@ static char *cppop (struct cpstack **pstack);
static int install_new_value (struct varobj *var, struct value *value,
int initial);
-static void install_default_visualizer (struct varobj *var);
-
/* Language-specific routines. */
static enum varobj_languages variable_language (struct varobj *var);
@@ -623,7 +653,6 @@ varobj_create (char *objname,
}
}
- install_default_visualizer (var);
discard_cleanups (old_chain);
return var;
}
@@ -738,15 +767,8 @@ instantiate_pretty_printer (PyObject *constructor, struct value *value)
#if HAVE_PYTHON
PyObject *val_obj = NULL;
PyObject *printer;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- value = value_copy (value);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
val_obj = value_to_value_object (value);
-
if (! val_obj)
return NULL;
@@ -810,6 +832,17 @@ varobj_get_display_hint (struct varobj *var)
return result;
}
+/* Return true if the varobj has items after TO, false otherwise. */
+
+int
+varobj_has_more (struct varobj *var, int to)
+{
+ if (VEC_length (varobj_p, var->children) > to)
+ return 1;
+ return ((to == -1 || VEC_length (varobj_p, var->children) == to)
+ && var->saved_item != NULL);
+}
+
/* If the variable object is bound to a specific thread, that
is its evaluation can always be done in context of a frame
inside that thread, returns GDB id of the thread -- which
@@ -842,22 +875,97 @@ varobj_get_frozen (struct varobj *var)
return var->frozen;
}
+/* A helper function that restricts a range to what is actually
+ available in a VEC. This follows the usual rules for the meaning
+ of FROM and TO -- if either is negative, the entire range is
+ used. */
+
+static void
+restrict_range (VEC (varobj_p) *children, int *from, int *to)
+{
+ if (*from < 0 || *to < 0)
+ {
+ *from = 0;
+ *to = VEC_length (varobj_p, children);
+ }
+ else
+ {
+ if (*from > VEC_length (varobj_p, children))
+ *from = VEC_length (varobj_p, children);
+ if (*to > VEC_length (varobj_p, children))
+ *to = VEC_length (varobj_p, children);
+ if (*from > *to)
+ *from = *to;
+ }
+}
+
+/* A helper for update_dynamic_varobj_children that installs a new
+ child when needed. */
+
+static void
+install_dynamic_child (struct varobj *var,
+ VEC (varobj_p) **changed,
+ VEC (varobj_p) **new,
+ VEC (varobj_p) **unchanged,
+ int *cchanged,
+ int index,
+ const char *name,
+ struct value *value)
+{
+ if (VEC_length (varobj_p, var->children) < index + 1)
+ {
+ /* There's no child yet. */
+ struct varobj *child = varobj_add_child (var, name, value);
+ if (new)
+ {
+ VEC_safe_push (varobj_p, *new, child);
+ *cchanged = 1;
+ }
+ }
+ else
+ {
+ varobj_p existing = VEC_index (varobj_p, var->children, index);
+ if (install_new_value (existing, value, 0))
+ {
+ if (changed)
+ VEC_safe_push (varobj_p, *changed, existing);
+ }
+ else if (unchanged)
+ VEC_safe_push (varobj_p, *unchanged, existing);
+ }
+}
+
+#if HAVE_PYTHON
+
+static int
+dynamic_varobj_has_child_method (struct varobj *var)
+{
+ struct cleanup *back_to;
+ PyObject *printer = var->pretty_printer;
+ int result;
+
+ back_to = varobj_ensure_python_env (var);
+ result = PyObject_HasAttr (printer, gdbpy_children_cst);
+ do_cleanups (back_to);
+ return result;
+}
+
+#endif
+
static int
update_dynamic_varobj_children (struct varobj *var,
VEC (varobj_p) **changed,
- VEC (varobj_p) **new_and_unchanged,
- int *cchanged)
-
+ VEC (varobj_p) **new,
+ VEC (varobj_p) **unchanged,
+ int *cchanged,
+ int update_children,
+ int from,
+ int to)
{
#if HAVE_PYTHON
- /* FIXME: we *might* want to provide this functionality as
- a standalone function, so that other interested parties
- than varobj code can benefit for this. */
struct cleanup *back_to;
PyObject *children;
- PyObject *iterator;
int i;
- int children_changed = 0;
PyObject *printer = var->pretty_printer;
back_to = varobj_ensure_python_env (var);
@@ -869,87 +977,106 @@ update_dynamic_varobj_children (struct varobj *var,
return 0;
}
- children = PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
- NULL);
-
- if (!children)
+ if (update_children || !var->child_iter)
{
- gdbpy_print_stack ();
- error (_("Null value returned for children"));
- }
+ children = PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
+ NULL);
+
+ if (!children)
+ {
+ gdbpy_print_stack ();
+ error (_("Null value returned for children"));
+ }
- make_cleanup_py_decref (children);
+ make_cleanup_py_decref (children);
- if (!PyIter_Check (children))
- error (_("Returned value is not iterable"));
+ if (!PyIter_Check (children))
+ error (_("Returned value is not iterable"));
- iterator = PyObject_GetIter (children);
- if (!iterator)
- {
- gdbpy_print_stack ();
- error (_("Could not get children iterator"));
+ Py_XDECREF (var->child_iter);
+ var->child_iter = PyObject_GetIter (children);
+ if (!var->child_iter)
+ {
+ gdbpy_print_stack ();
+ error (_("Could not get children iterator"));
+ }
+
+ Py_XDECREF (var->saved_item);
+ var->saved_item = NULL;
+
+ i = 0;
}
- make_cleanup_py_decref (iterator);
+ else
+ i = VEC_length (varobj_p, var->children);
- for (i = 0; ; ++i)
+ /* We ask for one extra child, so that MI can report whether there
+ are more children. */
+ for (; to < 0 || i < to + 1; ++i)
{
- PyObject *item = PyIter_Next (iterator);
- PyObject *py_v;
- struct value *v;
- char *name;
- struct cleanup *inner;
-
- if (!item)
- break;
- inner = make_cleanup_py_decref (item);
+ PyObject *item;
- if (!PyArg_ParseTuple (item, "sO", &name, &py_v))
- error (_("Invalid item from the child list"));
-
- v = convert_value_from_python (py_v);
+ /* See if there was a leftover from last time. */
+ if (var->saved_item)
+ {
+ item = var->saved_item;
+ var->saved_item = NULL;
+ }
+ else
+ item = PyIter_Next (var->child_iter);
- /* TODO: This assume the name of the i-th child never changes. */
+ if (!item)
+ break;
- /* Now see what to do here. */
- if (VEC_length (varobj_p, var->children) < i + 1)
+ /* We don't want to push the extra child on any report list. */
+ if (to < 0 || i < to)
{
- /* There's no child yet. */
- struct varobj *child = varobj_add_child (var, name, v);
- if (new_and_unchanged)
- VEC_safe_push (varobj_p, *new_and_unchanged, child);
- children_changed = 1;
+ PyObject *py_v;
+ char *name;
+ struct value *v;
+ struct cleanup *inner;
+ int can_mention = from < 0 || i >= from;
+
+ inner = make_cleanup_py_decref (item);
+
+ if (!PyArg_ParseTuple (item, "sO", &name, &py_v))
+ error (_("Invalid item from the child list"));
+
+ v = convert_value_from_python (py_v);
+ install_dynamic_child (var, can_mention ? changed : NULL,
+ can_mention ? new : NULL,
+ can_mention ? unchanged : NULL,
+ can_mention ? cchanged : NULL, i, name, v);
+ do_cleanups (inner);
}
- else
+ else
{
- varobj_p existing = VEC_index (varobj_p, var->children, i);
- if (install_new_value (existing, v, 0) && changed)
- {
- if (changed)
- VEC_safe_push (varobj_p, *changed, existing);
- }
- else
- {
- if (new_and_unchanged)
- VEC_safe_push (varobj_p, *new_and_unchanged, existing);
- }
- }
+ Py_XDECREF (var->saved_item);
+ var->saved_item = item;
- do_cleanups (inner);
+ /* We want to truncate the child list just before this
+ element. */
+ break;
+ }
}
if (i < VEC_length (varobj_p, var->children))
{
- int i;
- children_changed = 1;
- for (i = 0; i < VEC_length (varobj_p, var->children); ++i)
- varobj_delete (VEC_index (varobj_p, var->children, i), NULL, 0);
+ int j;
+ *cchanged = 1;
+ for (j = i; j < VEC_length (varobj_p, var->children); ++j)
+ varobj_delete (VEC_index (varobj_p, var->children, j), NULL, 0);
+ VEC_truncate (varobj_p, var->children, i);
}
- VEC_truncate (varobj_p, var->children, i);
+
+ /* If there are fewer children than requested, note that the list of
+ children changed. */
+ if (to >= 0 && VEC_length (varobj_p, var->children) < to)
+ *cchanged = 1;
+
var->num_children = VEC_length (varobj_p, var->children);
do_cleanups (back_to);
- *cchanged = children_changed;
return 1;
#else
gdb_assert (0 && "should never be called if Python is not enabled");
@@ -961,20 +1088,27 @@ varobj_get_num_children (struct varobj *var)
{
if (var->num_children == -1)
{
- int changed;
- if (!var->pretty_printer
- || !update_dynamic_varobj_children (var, NULL, NULL, &changed))
+ if (var->pretty_printer)
+ {
+ int dummy;
+
+ /* If we have a dynamic varobj, don't report -1 children.
+ So, try to fetch some children first. */
+ update_dynamic_varobj_children (var, NULL, NULL, NULL, &dummy,
+ 0, 0, 0);
+ }
+ else
var->num_children = number_of_children (var);
}
- return var->num_children;
+ return var->num_children >= 0 ? var->num_children : 0;
}
/* Creates a list of the immediate children of a variable object;
the return code is the number of such children or -1 on error */
VEC (varobj_p)*
-varobj_list_children (struct varobj *var)
+varobj_list_children (struct varobj *var, int *from, int *to)
{
struct varobj *child;
char *name;
@@ -982,12 +1116,16 @@ varobj_list_children (struct varobj *var)
var->children_requested = 1;
- if (var->pretty_printer
+ if (var->pretty_printer)
+ {
/* This, in theory, can result in the number of children changing without
frontend noticing. But well, calling -var-list-children on the same
varobj twice is not something a sane frontend would do. */
- && update_dynamic_varobj_children (var, NULL, NULL, &children_changed))
- return var->children;
+ update_dynamic_varobj_children (var, NULL, NULL, NULL, &children_changed,
+ 0, 0, *to);
+ restrict_range (var->children, from, to);
+ return var->children;
+ }
if (var->num_children == -1)
var->num_children = number_of_children (var);
@@ -1013,10 +1151,10 @@ varobj_list_children (struct varobj *var)
name = name_of_child (var, i);
existing = create_child (var, i, name);
VEC_replace (varobj_p, var->children, i, existing);
- install_default_visualizer (existing);
}
}
+ restrict_range (var->children, from, to);
return var->children;
}
@@ -1027,7 +1165,6 @@ varobj_add_child (struct varobj *var, const char *name, struct value *value)
VEC_length (varobj_p, var->children),
name, value);
VEC_safe_push (varobj_p, var->children, v);
- install_default_visualizer (v);
return v;
}
@@ -1089,6 +1226,12 @@ varobj_get_attributes (struct varobj *var)
return attributes;
}
+int
+varobj_pretty_printed_p (struct varobj *var)
+{
+ return var->pretty_printer != NULL;
+}
+
char *
varobj_get_formatted_value (struct varobj *var,
enum varobj_display_formats format)
@@ -1166,6 +1309,116 @@ varobj_set_value (struct varobj *var, char *expression)
return 1;
}
+#if HAVE_PYTHON
+
+/* A helper function to install a constructor function and visualizer
+ in a varobj. */
+
+static void
+install_visualizer (struct varobj *var, PyObject *constructor,
+ PyObject *visualizer)
+{
+ Py_XDECREF (var->constructor);
+ var->constructor = constructor;
+
+ Py_XDECREF (var->pretty_printer);
+ var->pretty_printer = visualizer;
+
+ Py_XDECREF (var->child_iter);
+ var->child_iter = NULL;
+}
+
+/* Install the default visualizer for VAR. */
+
+static void
+install_default_visualizer (struct varobj *var)
+{
+ if (pretty_printing)
+ {
+ PyObject *pretty_printer = NULL;
+
+ if (var->value)
+ {
+ pretty_printer = gdbpy_get_varobj_pretty_printer (var->value);
+ if (! pretty_printer)
+ {
+ gdbpy_print_stack ();
+ error (_("Cannot instantiate printer for default visualizer"));
+ }
+ }
+
+ if (pretty_printer == Py_None)
+ {
+ Py_DECREF (pretty_printer);
+ pretty_printer = NULL;
+ }
+
+ install_visualizer (var, NULL, pretty_printer);
+ }
+}
+
+/* Instantiate and install a visualizer for VAR using CONSTRUCTOR to
+ make a new object. */
+
+static void
+construct_visualizer (struct varobj *var, PyObject *constructor)
+{
+ PyObject *pretty_printer;
+
+ Py_INCREF (constructor);
+ if (constructor == Py_None)
+ pretty_printer = NULL;
+ else
+ {
+ pretty_printer = instantiate_pretty_printer (constructor, var->value);
+ if (! pretty_printer)
+ {
+ gdbpy_print_stack ();
+ Py_DECREF (constructor);
+ constructor = Py_None;
+ Py_INCREF (constructor);
+ }
+
+ if (pretty_printer == Py_None)
+ {
+ Py_DECREF (pretty_printer);
+ pretty_printer = NULL;
+ }
+ }
+
+ install_visualizer (var, constructor, pretty_printer);
+}
+
+#endif /* HAVE_PYTHON */
+
+/* A helper function for install_new_value. This creates and installs
+ a visualizer for VAR, if appropriate. */
+
+static void
+install_new_value_visualizer (struct varobj *var)
+{
+#if HAVE_PYTHON
+ /* If the constructor is None, then we want the raw value. If VAR
+ does not have a value, just skip this. */
+ if (var->constructor != Py_None && var->value)
+ {
+ struct cleanup *cleanup;
+ PyObject *pretty_printer = NULL;
+
+ cleanup = varobj_ensure_python_env (var);
+
+ if (!var->constructor)
+ install_default_visualizer (var);
+ else
+ construct_visualizer (var, var->constructor);
+
+ do_cleanups (cleanup);
+ }
+#else
+ /* Do nothing. */
+#endif
+}
+
/* Assign a new value to a variable object. If INITIAL is non-zero,
this is the first assignement after the variable object was just
created, or changed type. In that case, just assign the value
@@ -1206,10 +1459,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
that in C++ a reference is not rebindable, it cannot
meaningfully change. So, get hold of the real value. */
if (value)
- {
- value = coerce_ref (value);
- release_value (value);
- }
+ value = coerce_ref (value);
if (var->type && TYPE_CODE (var->type) == TYPE_CODE_UNION)
/* For unions, we need to fetch the value implicitly because
@@ -1256,7 +1506,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
values. Don't get string rendering if the value is
lazy -- if it is, the code above has decided that the value
should not be fetched. */
- if (value && !value_lazy (value))
+ if (value && !value_lazy (value) && !var->pretty_printer)
print_value = value_get_print_value (value, var->format, var);
/* If the type is changeable, compare the old and the new values.
@@ -1272,7 +1522,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
{
changed = 1;
}
- else
+ else if (! var->pretty_printer)
{
/* Try to compare the values. That requires that both
values are non-lazy. */
@@ -1317,74 +1567,53 @@ install_new_value (struct varobj *var, struct value *value, int initial)
if (var->value != NULL && var->value != value)
value_free (var->value);
var->value = value;
- if (var->print_value)
- xfree (var->print_value);
- var->print_value = print_value;
+ if (value != NULL)
+ value_incref (value);
if (value && value_lazy (value) && intentionally_not_fetched)
var->not_fetched = 1;
else
var->not_fetched = 0;
var->updated = 0;
+ install_new_value_visualizer (var);
+
+ /* If we installed a pretty-printer, re-compare the printed version
+ to see if the variable changed. */
+ if (var->pretty_printer)
+ {
+ xfree (print_value);
+ print_value = value_get_print_value (var->value, var->format, var);
+ if (!var->print_value || strcmp (var->print_value, print_value) != 0)
+ changed = 1;
+ }
+ if (var->print_value)
+ xfree (var->print_value);
+ var->print_value = print_value;
+
gdb_assert (!var->value || value_type (var->value));
return changed;
}
-static void
-install_visualizer (struct varobj *var, PyObject *visualizer)
+/* Return the requested range for a varobj. VAR is the varobj. FROM
+ and TO are out parameters; *FROM and *TO will be set to the
+ selected sub-range of VAR. If no range was selected using
+ -var-set-update-range, then both will be -1. */
+void
+varobj_get_child_range (struct varobj *var, int *from, int *to)
{
-#if HAVE_PYTHON
- /* If there are any children now, wipe them. */
- varobj_delete (var, NULL, 1 /* children only */);
- var->num_children = -1;
-
- Py_XDECREF (var->pretty_printer);
- var->pretty_printer = visualizer;
-
- install_new_value (var, var->value, 1);
-
- /* If we removed the visualizer, and the user ever requested the
- object's children, then we must compute the list of children.
- Note that we needn't do this when installing a visualizer,
- because updating will recompute dynamic children. */
- if (!visualizer && var->children_requested)
- varobj_list_children (var);
-#else
- error (_("Python support required"));
-#endif
+ *from = var->from;
+ *to = var->to;
}
-static void
-install_default_visualizer (struct varobj *var)
+/* Set the selected sub-range of children of VAR to start at index
+ FROM and end at index TO. If either FROM or TO is less than zero,
+ this is interpreted as a request for all children. */
+void
+varobj_set_child_range (struct varobj *var, int from, int to)
{
-#if HAVE_PYTHON
- struct cleanup *cleanup;
- PyObject *pretty_printer = NULL;
-
- cleanup = varobj_ensure_python_env (var);
-
- if (var->value)
- {
- pretty_printer = gdbpy_get_varobj_pretty_printer (var->value);
- if (! pretty_printer)
- {
- gdbpy_print_stack ();
- error (_("Cannot instantiate printer for default visualizer"));
- }
- }
-
- if (pretty_printer == Py_None)
- {
- Py_DECREF (pretty_printer);
- pretty_printer = NULL;
- }
-
- install_visualizer (var, pretty_printer);
- do_cleanups (cleanup);
-#else
- /* No error is right as this function is inserted just as a hook. */
-#endif
+ var->from = from;
+ var->to = to;
}
void
@@ -1402,31 +1631,19 @@ varobj_set_visualizer (struct varobj *var, const char *visualizer)
make_cleanup_py_decref (globals);
constructor = PyRun_String (visualizer, Py_eval_input, globals, globals);
-
- /* Do not instantiate NoneType. */
- if (constructor == Py_None)
- {
- pretty_printer = Py_None;
- Py_INCREF (pretty_printer);
- }
- else
- pretty_printer = instantiate_pretty_printer (constructor, var->value);
-
- Py_XDECREF (constructor);
- if (! pretty_printer)
+ if (! constructor)
{
gdbpy_print_stack ();
error (_("Could not evaluate visualizer expression: %s"), visualizer);
}
- if (pretty_printer == Py_None)
- {
- Py_DECREF (pretty_printer);
- pretty_printer = NULL;
- }
+ construct_visualizer (var, constructor);
+ Py_XDECREF (constructor);
- install_visualizer (var, pretty_printer);
+ /* If there are any children now, wipe them. */
+ varobj_delete (var, NULL, 1 /* children only */);
+ var->num_children = -1;
do_cleanups (back_to);
#else
@@ -1537,44 +1754,75 @@ VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit)
/* We probably should not get children of a varobj that has a
pretty-printer, but for which -var-list-children was never
- invoked. Presumably, such varobj is not yet expanded in the
- UI, so we need not bother getting it. */
+ invoked. */
if (v->pretty_printer)
{
- VEC (varobj_p) *changed = 0, *new_and_unchanged = 0;
+ VEC (varobj_p) *changed = 0, *new = 0, *unchanged = 0;
int i, children_changed;
varobj_p tmp;
- if (!v->children_requested)
- continue;
-
if (v->frozen)
continue;
+ if (!v->children_requested)
+ {
+ int dummy;
+
+ /* If we initially did not have potential children, but
+ now we do, consider the varobj as changed.
+ Otherwise, if children were never requested, consider
+ it as unchanged -- presumably, such varobj is not yet
+ expanded in the UI, so we need not bother getting
+ it. */
+ if (!varobj_has_more (v, 0))
+ {
+ update_dynamic_varobj_children (v, NULL, NULL, NULL,
+ &dummy, 0, 0, 0);
+ if (varobj_has_more (v, 0))
+ r.changed = 1;
+ }
+
+ if (r.changed)
+ VEC_safe_push (varobj_update_result, result, &r);
+
+ continue;
+ }
+
/* If update_dynamic_varobj_children returns 0, then we have
a non-conforming pretty-printer, so we skip it. */
- if (update_dynamic_varobj_children (v, &changed, &new_and_unchanged,
- &children_changed))
+ if (update_dynamic_varobj_children (v, &changed, &new, &unchanged,
+ &children_changed, 1,
+ v->from, v->to))
{
- if (children_changed)
- r.children_changed = 1;
- for (i = 0; VEC_iterate (varobj_p, changed, i, tmp); ++i)
+ if (children_changed || new)
{
- varobj_update_result r = {tmp};
- r.changed = 1;
- r.value_installed = 1;
- VEC_safe_push (varobj_update_result, stack, &r);
+ r.children_changed = 1;
+ r.new = new;
}
- for (i = 0;
- VEC_iterate (varobj_p, new_and_unchanged, i, tmp);
- ++i)
+ for (i = 0; VEC_iterate (varobj_p, changed, i, tmp); ++i)
{
varobj_update_result r = {tmp};
+ r.changed = 1;
r.value_installed = 1;
VEC_safe_push (varobj_update_result, stack, &r);
}
+ for (i = 0; VEC_iterate (varobj_p, unchanged, i, tmp); ++i)
+ {
+ if (!tmp->frozen)
+ {
+ varobj_update_result r = {tmp};
+ r.value_installed = 1;
+ VEC_safe_push (varobj_update_result, stack, &r);
+ }
+ }
if (r.changed || r.children_changed)
VEC_safe_push (varobj_update_result, result, &r);
+
+ /* Free CHANGED and UNCHANGED, but not NEW, because NEW
+ has been put into the result vector. */
+ VEC_free (varobj_p, changed);
+ VEC_free (varobj_p, unchanged);
+
continue;
}
}
@@ -1862,7 +2110,12 @@ new_variable (void)
var->frozen = 0;
var->not_fetched = 0;
var->children_requested = 0;
+ var->from = -1;
+ var->to = -1;
+ var->constructor = 0;
var->pretty_printer = 0;
+ var->child_iter = 0;
+ var->saved_item = 0;
return var;
}
@@ -1892,7 +2145,10 @@ free_variable (struct varobj *var)
if (var->pretty_printer)
{
struct cleanup *cleanup = varobj_ensure_python_env (var);
- Py_DECREF (var->pretty_printer);
+ Py_XDECREF (var->constructor);
+ Py_XDECREF (var->pretty_printer);
+ Py_XDECREF (var->child_iter);
+ Py_XDECREF (var->saved_item);
do_cleanups (cleanup);
}
#endif
@@ -2139,6 +2395,8 @@ value_of_root (struct varobj **var_handle, int *type_changed)
else
{
tmp_var->obj_name = xstrdup (var->obj_name);
+ tmp_var->from = var->from;
+ tmp_var->to = var->to;
varobj_delete (var, NULL, 0);
install_variable (tmp_var);
@@ -2173,7 +2431,11 @@ static char *
my_value_of_variable (struct varobj *var, enum varobj_display_formats format)
{
if (var->root->is_valid)
- return (*var->root->lang->value_of_variable) (var, format);
+ {
+ if (var->pretty_printer)
+ return value_get_print_value (var->value, var->format, var);
+ return (*var->root->lang->value_of_variable) (var, format);
+ }
else
return NULL;
}
@@ -2196,43 +2458,51 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
struct cleanup *back_to = varobj_ensure_python_env (var);
PyObject *value_formatter = var->pretty_printer;
- if (value_formatter && PyObject_HasAttr (value_formatter,
- gdbpy_to_string_cst))
+ if (value_formatter)
{
- char *hint;
- struct value *replacement;
- int string_print = 0;
- PyObject *output = NULL;
+ /* First check to see if we have any children at all. If so,
+ we simply return {...}. */
+ if (dynamic_varobj_has_child_method (var))
+ return xstrdup ("{...}");
- hint = gdbpy_get_display_hint (value_formatter);
- if (hint)
+ if (PyObject_HasAttr (value_formatter, gdbpy_to_string_cst))
{
- if (!strcmp (hint, "string"))
- string_print = 1;
- xfree (hint);
- }
+ char *hint;
+ struct value *replacement;
+ int string_print = 0;
+ PyObject *output = NULL;
+
+ hint = gdbpy_get_display_hint (value_formatter);
+ if (hint)
+ {
+ if (!strcmp (hint, "string"))
+ string_print = 1;
+ xfree (hint);
+ }
- output = apply_varobj_pretty_printer (value_formatter,
- &replacement);
- if (output)
- {
- PyObject *py_str = python_string_to_target_python_string (output);
- if (py_str)
- {
- char *s = PyString_AsString (py_str);
- len = PyString_Size (py_str);
- thevalue = xmemdup (s, len + 1, len + 1);
- Py_DECREF (py_str);
+ output = apply_varobj_pretty_printer (value_formatter,
+ &replacement);
+ if (output)
+ {
+ PyObject *py_str
+ = python_string_to_target_python_string (output);
+ if (py_str)
+ {
+ char *s = PyString_AsString (py_str);
+ len = PyString_Size (py_str);
+ thevalue = xmemdup (s, len + 1, len + 1);
+ Py_DECREF (py_str);
+ }
+ Py_DECREF (output);
}
- Py_DECREF (output);
- }
- if (thevalue && !string_print)
- {
- do_cleanups (back_to);
- return thevalue;
+ if (thevalue && !string_print)
+ {
+ do_cleanups (back_to);
+ return thevalue;
+ }
+ if (replacement)
+ value = replacement;
}
- if (replacement)
- value = replacement;
}
do_cleanups (back_to);
}
@@ -2961,10 +3231,7 @@ cplus_describe_child (struct varobj *parent, int index,
*cname = xstrdup (TYPE_FIELD_NAME (type, index));
if (cvalue && value)
- {
- *cvalue = value_cast (TYPE_FIELD_TYPE (type, index), value);
- release_value (*cvalue);
- }
+ *cvalue = value_cast (TYPE_FIELD_TYPE (type, index), value);
if (ctype)
{
diff --git a/gdb/varobj.h b/gdb/varobj.h
index 7297243..f43c593 100644
--- a/gdb/varobj.h
+++ b/gdb/varobj.h
@@ -78,6 +78,12 @@ typedef struct varobj_update_result_t
new value of varobj is already computed and installed, or has to
be yet installed. Don't use this outside varobj.c */
int value_installed;
+
+ /* This will be non-NULL when new children were added to the varobj.
+ It lists the new children (which must necessarily come at the end
+ of the child list) added during an update. The caller is
+ responsible for freeing this vector. */
+ VEC (varobj_p) *new;
} varobj_update_result;
DEF_VEC_O (varobj_update_result);
@@ -112,13 +118,24 @@ extern void varobj_set_frozen (struct varobj *var, int frozen);
extern int varobj_get_frozen (struct varobj *var);
+extern void varobj_get_child_range (struct varobj *var, int *from, int *to);
+
+extern void varobj_set_child_range (struct varobj *var, int from, int to);
+
extern char *varobj_get_display_hint (struct varobj *var);
extern int varobj_get_num_children (struct varobj *var);
-/* Return the list of children of VAR. The returned vector
- should not be modified in any way. */
-extern VEC (varobj_p)* varobj_list_children (struct varobj *var);
+/* Return the list of children of VAR. The returned vector should not
+ be modified in any way. FROM and TO are in/out parameters
+ indicating the range of children to return. If either *FROM or *TO
+ is less than zero on entry, then all children will be returned. On
+ return, *FROM and *TO will be updated to indicate the real range
+ that was returned. The resulting VEC will contain at least the
+ children from *FROM to just before *TO; it might contain more
+ children, depending on whether any more were available. */
+extern VEC (varobj_p)* varobj_list_children (struct varobj *var,
+ int *from, int *to);
extern char *varobj_get_type (struct varobj *var);
@@ -149,6 +166,13 @@ extern int varobj_editable_p (struct varobj *var);
extern int varobj_floating_p (struct varobj *var);
-extern void varobj_set_visualizer (struct varobj *var, const char *visualizer);
+extern void
+varobj_set_visualizer (struct varobj *var, const char *visualizer);
+
+extern void varobj_enable_pretty_printing (void);
+
+extern int varobj_has_more (struct varobj *var, int to);
+
+extern int varobj_pretty_printed_p (struct varobj *var);
#endif /* VAROBJ_H */
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-14 20:03 ` Tom Tromey
@ 2009-09-14 20:22 ` Eli Zaretskii
2009-09-14 21:29 ` Tom Tromey
0 siblings, 1 reply; 39+ messages in thread
From: Eli Zaretskii @ 2009-09-14 20:22 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
> From: Tom Tromey <tromey@redhat.com>
> Cc: gdb-patches@sourceware.org
> Date: Mon, 14 Sep 2009 14:03:05 -0600
>
> Tom> +This operation returns attributes of the newly-created varobj. These
> Tom> +include, but are not limited to:
>
> Eli> Why don't we have an exhaustive list here?
>
> We may add attributes later.
Then I don't see a need to have the "not limited to" part. When we
add more attributes, we should add them to the list.
> Tom> +For a dynamic varobj, this value cannot reliably be used to form an
> Tom> +expression. Also, a dynamic varobj will not report the access
> Tom> +qualifying pseudo-children, regardless of the language.
>
> Eli> Do we want to give the reader some hints as to how to achieve these
> Eli> with dynamic varobjs?
>
> There is no way to do these.
I suggest to say so, then.
Thanks.
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-14 20:05 ` Tom Tromey
@ 2009-09-14 20:24 ` Eli Zaretskii
2009-09-14 23:58 ` Nick Roberts
1 sibling, 0 replies; 39+ messages in thread
From: Eli Zaretskii @ 2009-09-14 20:24 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
> From: Tom Tromey <tromey@redhat.com>
> Date: Mon, 14 Sep 2009 14:04:51 -0600
>
> I tried to address all the documentation comments.
Thanks. Apart of the two minor comments in my last mail, I'm happy
with the documentation.
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-14 20:22 ` Eli Zaretskii
@ 2009-09-14 21:29 ` Tom Tromey
2009-09-15 3:06 ` Eli Zaretskii
0 siblings, 1 reply; 39+ messages in thread
From: Tom Tromey @ 2009-09-14 21:29 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches
>>>>> "Eli" == Eli Zaretskii <eliz@gnu.org> writes:
Eli> Then I don't see a need to have the "not limited to" part. When we
Eli> add more attributes, we should add them to the list.
Ok.
Tom> +For a dynamic varobj, this value cannot reliably be used to form an
Eli> Do we want to give the reader some hints as to how to achieve these
Eli> with dynamic varobjs?
>> There is no way to do these.
Eli> I suggest to say so, then.
Done.
Here's a new version with all your comments addressed.
Tom
2009-09-14 Tom Tromey <tromey@redhat.com>
* varobj.h (varobj_update_result_t) <new>: New field.
(varobj_get_child_range, varobj_set_child_range): Declare.
(varobj_list_children): Update.
(varobj_enable_pretty_printing, varobj_has_more)
(varobj_pretty_printed_p): Declare.
* varobj.c (pretty_printing): New global.
(varobj_enable_pretty_printing): New function.
(struct varobj_root) <from, to, constructor, child_iter,
saved_item>: New fields.
(varobj_create): Don't call install_default_visualizer.
(instantiate_pretty_printer): Don't use value_copy.
(varobj_has_more): New function.
(restrict_range): New function.
(install_dynamic_child): Likewise.
(dynamic_varobj_has_child_method): Likewise.
(update_dynamic_varobj_children): Remove 'new_and_unchanged'
argument; add 'new', 'unchanged', 'from', and 'to' arguments.
Rewrite.
(varobj_get_num_children): Call update_dynamic_varobj_children.
(varobj_list_children): Add 'from' and 'to' arguments. Ignore
result of update_dynamic_varobj_children. Don't call
install_default_visualizer. Restrict result range.
(varobj_add_child): Don't call install_default_visualizer.
(varobj_pretty_printed_p): New function.
(install_visualizer): Rewrite. Move earlier in file.
(install_default_visualizer): Likewise.
(construct_visualizer): New function.
(install_new_value_visualizer): Likewise.
(install_new_value): Don't call release_value. Special case
pretty-printed objects. Use value_incref. Rearrange "changed"
logic.
(varobj_get_child_range): New function.
(varobj_set_child_range): Likewise.
(varobj_set_visualizer): Rewrite.
(varobj_update): Rewrite pretty-printing logic.
(new_variable): Initialize new fields.
(free_variable): Destroy new fields.
(value_of_root): Copy 'from' and 'to'.
(my_value_of_variable): Handle pretty-printers.
(value_get_print_value): Rework pretty-printing logic.
(cplus_describe_child): Don't use release_value.
* mi/mi-cmds.h (mi_cmd_enable_pretty_printing)
(mi_cmd_var_set_update_range): Declare.
* mi/mi-cmds.c (mi_cmds): Add enable-pretty-printing and
var-set-update-range.
* mi/mi-cmd-var.c (print_varobj): Update. Emit "dynamic"
attribute.
(mi_cmd_var_create): Emit "has_more" attribute.
(mi_cmd_var_set_format): Plug memory leak.
(mi_print_value_p): Replace 'type' argument with 'var'. Handle
pretty-printed varobjs.
(mi_cmd_var_list_children): Accept 'from' and 'to' arguments.
Emit "has_more" attribute.
(mi_cmd_var_evaluate_expression): Plug memory leak.
(mi_cmd_var_assign): Likewise.
(varobj_update_one): Likewise. Emit "dynamic", "has_more", and
"new_children" attributes.
(mi_cmd_enable_pretty_printing): New function.
(mi_cmd_var_set_update_range): Likewise.
2009-09-14 Tom Tromey <tromey@redhat.com>
* gdb.texinfo (GDB/MI Variable Objects): Document
-enable-pretty-printing, -var-set-update-range, dynamic varobjs.
Expand -var-update documentation.
2009-09-14 Tom Tromey <tromey@redhat.com>
* lib/mi-support.exp (mi_create_varobj): Update.
(mi_create_floating_varobj): Likewise.
(mi_create_dynamic_varobj): New proc.
(mi_varobj_update): Update.
(mi_varobj_update_with_type_change): Likewise.
(mi_varobj_update_kv_helper): New proc.
(mi_varobj_update_dynamic_helper): Rewrite.
(mi_varobj_update_dynamic): New proc.
(mi_list_varobj_children): Update.
(mi_list_varobj_children_range): Add 'from' and 'to' arguments.
* gdb.python/python-prettyprint.py (pp_outer): New class.
(pp_nullstr): Likewise.
(lookup_function): Register new printers.
* gdb.python/python-prettyprint.c (struct substruct): New type.
(struct outerstruct): Likewise.
(substruct_test): New function.
(struct nullstr): New type.
(string_1, string_2): New globals.
(main): Add new tests.
* gdb.python/python-mi.exp: Added regression tests.
* gdb.mi/mi2-var-display.exp: Update.
* gdb.mi/mi2-var-cmd.exp: Update.
* gdb.mi/mi2-var-child.exp: Update.
* gdb.mi/mi2-var-block.exp: Update.
* gdb.mi/mi-var-invalidate.exp: Update.
* gdb.mi/mi-var-display.exp: Update.
* gdb.mi/mi-var-cmd.exp: Update.
* gdb.mi/mi-var-child.exp: Update.
* gdb.mi/mi-var-block.exp: Update.
* gdb.mi/mi-break.exp: Update.
* gdb.mi/gdb701.exp: Update.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 7b26675..559f5ed 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -23360,6 +23360,8 @@ access this functionality:
@item @strong{Operation}
@tab @strong{Description}
+@item @code{-enable-pretty-printing}
+@tab enable Python-based pretty-printing
@item @code{-var-create}
@tab create a variable object
@item @code{-var-delete}
@@ -23388,6 +23390,8 @@ access this functionality:
@tab update the variable and its children
@item @code{-var-set-frozen}
@tab set frozeness attribute
+@item @code{-var-set-update-range}
+@tab set range of children to display on update
@end multitable
In the next subsection we describe each operation in detail and suggest
@@ -23395,6 +23399,23 @@ how it can be used.
@subheading Description And Use of Operations on Variable Objects
+@subheading The @code{-enable-pretty-printing} Command
+@findex -enable-pretty-printing
+
+@smallexample
+-enable-pretty-printing
+@end smallexample
+
+@value{GDBN} allows Python-based visualizers to affect the output of the
+MI variable object commands. However, because there was no way to
+implement this in a fully backward-compatible way, a front end must
+request that this functionality be enabled.
+
+Once enabled, this feature cannot be disabled.
+
+Note that if Python support has not been compiled into @value{GDBN},
+this command will still succeed (and do nothing).
+
@subheading The @code{-var-create} Command
@findex -var-create
@@ -23434,15 +23455,56 @@ begin with a @samp{*}), or one of the following:
@samp{$@var{regname}} --- a CPU register name
@end itemize
+@cindex dynamic varobj
+A varobj's contents may be provided by a Python-based pretty-printer. In this
+case the varobj is known as a @dfn{dynamic varobj}. Dynamic varobjs
+have slightly different semantics in some cases. If the
+@code{-enable-pretty-printing} command is not sent, then @value{GDBN}
+will never create a dynamic varobj. This ensures backward
+compatibility for existing clients.
+
@subsubheading Result
-This operation returns the name, number of children and the type of the
-object created. Type is returned as a string as the ones generated by
-the @value{GDBN} CLI. If a fixed variable object is bound to a
-specific thread, the thread is is also printed:
+This operation returns attributes of the newly-created varobj. These
+are:
+
+@table @samp
+@item name
+The name of the varobj.
+
+@item numchild
+The number of children of the varobj. This number is not necessarily
+reliable for a dynamic varobj. Instead, you must examine the
+@samp{has_more} attribute.
+
+@item value
+The varobj's scalar value. For a varobj whose type is some sort of
+aggregate (e.g., a @code{struct}), or for a dynamic varobj, this value
+will not be interesting.
+
+@item type
+The varobj's type. This is a string representation of the type, as
+would be printed by the @value{GDBN} CLI.
+
+@item thread-id
+If a variable object is bound to a specific thread, then this is the
+thread's identifier.
+
+@item has_more
+For a dynamic varobj, this indicates whether there appear to be any
+children available. For a non-dynamic varobj, this will be 0.
+
+@item dynamic
+This attribute will be present and have the value @samp{1} if the
+varobj is a dynamic varobj. If the varobj is not a dynamic varobj,
+then this attribute will not be present.
+@end table
+
+Typical output will look like this:
@smallexample
- name="@var{name}",numchild="@var{N}",type="@var{type}",thread-id="@var{M}"
+ name="@var{name}",numchild="@var{N}",type="@var{type}",thread-id="@var{M}",
+ has_more="@var{has_more}"
@end smallexample
@@ -23520,6 +23582,10 @@ Returns the number of children of a variable object @var{name}:
numchild=@var{n}
@end smallexample
+Note that this number is not completely reliable for a dynamic varobj.
+It will return the current number of children, but more children may
+be available.
+
@subheading The @code{-var-list-children} Command
@findex -var-list-children
@@ -23527,7 +23593,7 @@ Returns the number of children of a variable object @var{name}:
@subsubheading Synopsis
@smallexample
- -var-list-children [@var{print-values}] @var{name}
+ -var-list-children [@var{print-values}] @var{name} [@var{from} @var{to}]
@end smallexample
@anchor{-var-list-children}
@@ -23540,6 +23606,22 @@ values; and if it is 2 or @code{--simple-values} print the name and
value for simple data types and just the name for arrays, structures
and unions.
+@var{from} and @var{to}, if specified, indicate the range of children
+to report. If @var{from} or @var{to} is less than zero, the range is
+reset and all children will be reported. Otherwise, children starting
+at @var{from} (zero-based) and up to and excluding @var{to} will be
+reported.
+
+If a child range is requested, it will only affect the current call to
+@code{-var-list-children}, but not future calls to @code{-var-update}.
+For this, you must instead use @code{-var-set-update-range}. The
+intent of this approach is to enable a front end to implement any
+update approach it likes; for example, scrolling a view may cause the
+front end to request more children with @code{-var-list-children}, and
+then the front end could call @code{-var-set-update-range} with a
+different range to ensure that future updates are restricted to just
+the visible items.
+
For each child the following results are returned:
@table @var
@@ -23551,13 +23633,21 @@ Name of the variable object created for this child.
The expression to be shown to the user by the front end to designate this child.
For example this may be the name of a structure member.
+For a dynamic varobj, this value cannot be used to form an
+expression. There is no way to do this at all with a dynamic varobj.
+
For C/C@t{++} structures there are several pseudo children returned to
designate access qualifiers. For these pseudo children @var{exp} is
@samp{public}, @samp{private}, or @samp{protected}. In this case the
type and value are not present.
+A dynamic varobj will not report the access qualifying
+pseudo-children, regardless of the language. This information is not
+available at all with a dynamic varobj.
+
@item numchild
-Number of children this child has.
+Number of children this child has. For a dynamic varobj, this will be
+0.
@item type
The type of the child.
@@ -23573,6 +23663,19 @@ Otherwise this result is not present.
If the variable object is frozen, this variable will be present with a value of 1.
@end table
+The result may have its own attributes:
+
+@table @samp
+@item displayhint
+A dynamic varobj can supply a display hint to the front end. The
+value comes directly from the Python pretty-printer object's
+@code{display_hint} method. @xref{Pretty Printing}.
+
+@item has_more
+This is an integer attribute which is nonzero if there are children
+remaining after the end of the selected range.
+@end table
+
@subsubheading Example
@smallexample
@@ -23649,6 +23752,9 @@ result can be used only for UI presentation. Typical use of
the @code{-var-info-path-expression} command is creating a
watchpoint from a variable object.
+This command is currently not valid for children of a dynamic varobj,
+and will give an error when invoked on one.
+
For example, suppose @code{C} is a C@t{++} class, derived from class
@code{Base}, and that the @code{Base} class has a member called
@code{m_size}. Assume a variable @code{c} is has the type of
@@ -23754,21 +23860,25 @@ With the @samp{*} parameter, if a variable object is bound to a
currently running thread, it will not be updated, without any
diagnostic.
-@subsubheading Example
+If @code{-var-set-update-range} was previously used on a varobj, then
+only the selected range of children will be reported.
-@smallexample
-(gdb)
--var-assign var1 3
-^done,value="3"
-(gdb)
--var-update --all-values var1
-^done,changelist=[@{name="var1",value="3",in_scope="true",
-type_changed="false"@}]
-(gdb)
-@end smallexample
+@code{-var-update} reports all the changed varobjs in a tuple named
+@samp{changelist}.
+Each item in the change list is itself a tuple holding:
+
+@table @samp
+@item name
+The name of the varobj.
+
+@item value
+If values were requested for this update, then this field will be
+present and will hold the value of the varobj.
+
+@item in_scope
@anchor{-var-update}
-The field in_scope may take three values:
+This field is a string which may take one of three values:
@table @code
@item "true"
@@ -23790,6 +23900,61 @@ objects.
In the future new values may be added to this list so the front should
be prepared for this possibility. @xref{GDB/MI Development and Front Ends, ,@sc{GDB/MI} Development and Front Ends}.
+@item type_changed
+This is only present if the varobj is still valid. If the type
+changed, then this will be the string @samp{true}; otherwise it will
+be @samp{false}.
+
+@item new_type
+If the varobj's type changed, then this field will be present and will
+hold the new type.
+
+@item new_num_children
+For a dynamic varobj, if the number of children changed, or if the
+type changed, this will be the new number of children.
+
+The @samp{numchild} field in other varobj responses is generally not
+valid for a dynamic varobj -- it will show the number of children that
+@value{GDBN} knows about, but because dynamic varobjs lazily
+instantiate their children, this will not reflect the number of
+children which may be available.
+
+The @samp{new_num_children} attribute only reports changes to the
+number of children known by @value{GDBN}. This is the only way to
+detect whether an update has removed children (which necessarily can
+only happen at the end of the update range).
+
+@item displayhint
+The display hint, if any.
+
+@item has_more
+This is an integer value, which will be 1 if there are more children
+available outside the varobj's update range.
+
+@item dynamic
+This attribute will be present and have the value @samp{1} if the
+varobj is a dynamic varobj. If the varobj is not a dynamic varobj,
+then this attribute will not be present.
+
+@item new_children
+If new children were added to a dynamic varobj within the selected
+update range (as set by @code{-var-set-update-range}), then they will
+be listed in this attribute.
+@end table
+
+@subsubheading Example
+
+@smallexample
+(gdb)
+-var-assign var1 3
+^done,value="3"
+(gdb)
+-var-update --all-values var1
+^done,changelist=[@{name="var1",value="3",in_scope="true",
+type_changed="false"@}]
+(gdb)
+@end smallexample
+
@subheading The @code{-var-set-frozen} Command
@findex -var-set-frozen
@anchor{-var-set-frozen}
@@ -23821,6 +23986,32 @@ Unfreezing a variable does not update it, only subsequent
(gdb)
@end smallexample
+@subheading The @code{-var-set-update-range} command
+@findex -var-set-update-range
+@anchor{-var-set-update-range}
+
+@subsubheading Synopsis
+
+@smallexample
+ -var-set-update-range @var{name} @var{from} @var{to}
+@end smallexample
+
+Set the range of children to be returned by future invocations of
+@code{-var-update}.
+
+@var{from} and @var{to} indicate the range of children to report. If
+@var{from} or @var{to} is less than zero, the range is reset and all
+children will be reported. Otherwise, children starting at @var{from}
+(zero-based) and up to and excluding @var{to} will be reported.
+
+@subsubheading Example
+
+@smallexample
+(gdb)
+-var-set-update-range V 1 2
+^done
+@end smallexample
+
@subheading The @code{-var-set-visualizer} command
@findex -var-set-visualizer
@anchor{-var-set-visualizer}
diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c
index 0cf03d9..ede928c 100644
--- a/gdb/mi/mi-cmd-var.c
+++ b/gdb/mi/mi-cmd-var.c
@@ -41,7 +41,7 @@ static void varobj_update_one (struct varobj *var,
enum print_values print_values,
int explicit);
-static int mi_print_value_p (struct type *type, enum print_values print_values);
+static int mi_print_value_p (struct varobj *var, enum print_values print_values);
/* Print variable object VAR. The PRINT_VALUES parameter controls
if the value should be printed. The PRINT_EXPRESSION parameter
@@ -59,8 +59,12 @@ print_varobj (struct varobj *var, enum print_values print_values,
ui_out_field_string (uiout, "exp", varobj_get_expression (var));
ui_out_field_int (uiout, "numchild", varobj_get_num_children (var));
- if (mi_print_value_p (varobj_get_gdb_type (var), print_values))
- ui_out_field_string (uiout, "value", varobj_get_value (var));
+ if (mi_print_value_p (var, print_values))
+ {
+ char *val = varobj_get_value (var);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
+ }
type = varobj_get_type (var);
if (type != NULL)
@@ -75,6 +79,9 @@ print_varobj (struct varobj *var, enum print_values print_values,
if (varobj_get_frozen (var))
ui_out_field_int (uiout, "frozen", 1);
+
+ if (varobj_pretty_printed_p (var))
+ ui_out_field_int (uiout, "dynamic", 1);
}
/* VAROBJ operations */
@@ -138,6 +145,8 @@ mi_cmd_var_create (char *command, char **argv, int argc)
print_varobj (var, PRINT_ALL_VALUES, 0 /* don't print expression */);
+ ui_out_field_int (uiout, "has_more", varobj_has_more (var, 0));
+
do_cleanups (old_cleanups);
}
@@ -223,6 +232,7 @@ mi_cmd_var_set_format (char *command, char **argv, int argc)
{
enum varobj_display_formats format;
struct varobj *var;
+ char *val;
if (argc != 2)
error (_("mi_cmd_var_set_format: Usage: NAME FORMAT."));
@@ -239,7 +249,9 @@ mi_cmd_var_set_format (char *command, char **argv, int argc)
ui_out_field_string (uiout, "format", varobj_format_string[(int) format]);
/* Report the value in the new format */
- ui_out_field_string (uiout, "value", varobj_get_value (var));
+ val = varobj_get_value (var);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
}
void
@@ -337,11 +349,12 @@ Must be: 0 or \"%s\", 1 or \"%s\", 2 or \"%s\""),
}
/* Return 1 if given the argument PRINT_VALUES we should display
- a value of type TYPE. */
+ the varobj VAR. */
static int
-mi_print_value_p (struct type *type, enum print_values print_values)
+mi_print_value_p (struct varobj *var, enum print_values print_values)
{
+ struct type *type;
if (print_values == PRINT_NO_VALUES)
return 0;
@@ -349,6 +362,10 @@ mi_print_value_p (struct type *type, enum print_values print_values)
if (print_values == PRINT_ALL_VALUES)
return 1;
+ if (varobj_pretty_printed_p (var))
+ return 1;
+
+ type = varobj_get_gdb_type (var);
if (type == NULL)
return 1;
else
@@ -369,24 +386,35 @@ mi_cmd_var_list_children (char *command, char **argv, int argc)
struct varobj *var;
VEC(varobj_p) *children;
struct varobj *child;
- struct cleanup *cleanup_children;
int numchild;
enum print_values print_values;
int ix;
+ int from, to;
char *display_hint;
- if (argc != 1 && argc != 2)
- error (_("mi_cmd_var_list_children: Usage: [PRINT_VALUES] NAME"));
+ if (argc < 1 || argc > 4)
+ error (_("mi_cmd_var_list_children: Usage: [PRINT_VALUES] NAME [FROM TO]"));
/* Get varobj handle, if a valid var obj name was specified */
- if (argc == 1)
+ if (argc == 1 || argc == 3)
var = varobj_get_handle (argv[0]);
else
var = varobj_get_handle (argv[1]);
- children = varobj_list_children (var);
- ui_out_field_int (uiout, "numchild", VEC_length (varobj_p, children));
- if (argc == 2)
+ if (argc > 2)
+ {
+ from = atoi (argv[argc - 2]);
+ to = atoi (argv[argc - 1]);
+ }
+ else
+ {
+ from = -1;
+ to = -1;
+ }
+
+ children = varobj_list_children (var, &from, &to);
+ ui_out_field_int (uiout, "numchild", to - from);
+ if (argc == 2 || argc == 4)
print_values = mi_parse_values_option (argv[0]);
else
print_values = PRINT_NO_VALUES;
@@ -398,21 +426,28 @@ mi_cmd_var_list_children (char *command, char **argv, int argc)
xfree (display_hint);
}
- if (VEC_length (varobj_p, children) == 0)
- return;
-
- if (mi_version (uiout) == 1)
- cleanup_children = make_cleanup_ui_out_tuple_begin_end (uiout, "children");
- else
- cleanup_children = make_cleanup_ui_out_list_begin_end (uiout, "children");
- for (ix = 0; VEC_iterate (varobj_p, children, ix, child); ++ix)
+ if (from < to)
{
- struct cleanup *cleanup_child;
- cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, "child");
- print_varobj (child, print_values, 1 /* print expression */);
- do_cleanups (cleanup_child);
+ struct cleanup *cleanup_children;
+ if (mi_version (uiout) == 1)
+ cleanup_children
+ = make_cleanup_ui_out_tuple_begin_end (uiout, "children");
+ else
+ cleanup_children
+ = make_cleanup_ui_out_list_begin_end (uiout, "children");
+ for (ix = from;
+ ix < to && VEC_iterate (varobj_p, children, ix, child);
+ ++ix)
+ {
+ struct cleanup *cleanup_child;
+ cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, "child");
+ print_varobj (child, print_values, 1 /* print expression */);
+ do_cleanups (cleanup_child);
+ }
+ do_cleanups (cleanup_children);
}
- do_cleanups (cleanup_children);
+
+ ui_out_field_int (uiout, "has_more", varobj_has_more (var, to));
}
void
@@ -538,16 +573,24 @@ mi_cmd_var_evaluate_expression (char *command, char **argv, int argc)
var = varobj_get_handle (argv[optind]);
if (formatFound)
- ui_out_field_string (uiout, "value", varobj_get_formatted_value (var, format));
+ {
+ char *val = varobj_get_formatted_value (var, format);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
+ }
else
- ui_out_field_string (uiout, "value", varobj_get_value (var));
+ {
+ char *val = varobj_get_value (var);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
+ }
}
void
mi_cmd_var_assign (char *command, char **argv, int argc)
{
struct varobj *var;
- char *expression;
+ char *expression, *val;
if (argc != 2)
error (_("mi_cmd_var_assign: Usage: NAME EXPRESSION."));
@@ -563,7 +606,9 @@ mi_cmd_var_assign (char *command, char **argv, int argc)
if (!varobj_set_value (var, expression))
error (_("mi_cmd_var_assign: Could not assign expression to variable object"));
- ui_out_field_string (uiout, "value", varobj_get_value (var));
+ val = varobj_get_value (var);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
}
/* Type used for parameters passing to mi_cmd_var_update_iter. */
@@ -670,6 +715,7 @@ varobj_update_one (struct varobj *var, enum print_values print_values,
for (i = 0; VEC_iterate (varobj_update_result, changes, i, r); ++i)
{
char *display_hint;
+ int from, to;
if (mi_version (uiout) > 1)
cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
@@ -678,8 +724,12 @@ varobj_update_one (struct varobj *var, enum print_values print_values,
switch (r->status)
{
case VAROBJ_IN_SCOPE:
- if (mi_print_value_p (varobj_get_gdb_type (r->varobj), print_values))
- ui_out_field_string (uiout, "value", varobj_get_value (r->varobj));
+ if (mi_print_value_p (r->varobj, print_values))
+ {
+ char *val = varobj_get_value (r->varobj);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
+ }
ui_out_field_string (uiout, "in_scope", "true");
break;
case VAROBJ_NOT_IN_SCOPE:
@@ -699,11 +749,11 @@ varobj_update_one (struct varobj *var, enum print_values print_values,
}
if (r->type_changed)
- {
- ui_out_field_string (uiout, "new_type", varobj_get_type (r->varobj));
- ui_out_field_int (uiout, "new_num_children",
- varobj_get_num_children (r->varobj));
- }
+ ui_out_field_string (uiout, "new_type", varobj_get_type (r->varobj));
+
+ if (r->type_changed || r->children_changed)
+ ui_out_field_int (uiout, "new_num_children",
+ varobj_get_num_children (r->varobj));
display_hint = varobj_get_display_hint (var);
if (display_hint)
@@ -712,28 +762,59 @@ varobj_update_one (struct varobj *var, enum print_values print_values,
xfree (display_hint);
}
- if (r->children_changed)
- {
- int ix;
- struct varobj *child;
- struct cleanup *cleanup =
- make_cleanup_ui_out_list_begin_end (uiout, "children");
+ if (varobj_pretty_printed_p (var))
+ ui_out_field_int (uiout, "dynamic", 1);
- VEC (varobj_p)* children = varobj_list_children (r->varobj);
+ varobj_get_child_range (r->varobj, &from, &to);
+ ui_out_field_int (uiout, "has_more",
+ varobj_has_more (r->varobj, to));
- for (ix = 0; VEC_iterate (varobj_p, children, ix, child); ++ix)
+ if (r->new)
+ {
+ int j;
+ varobj_p child;
+ struct cleanup *cleanup;
+
+ cleanup = make_cleanup_ui_out_list_begin_end (uiout, "new_children");
+ for (j = 0; VEC_iterate (varobj_p, r->new, j, child); ++j)
{
struct cleanup *cleanup_child;
cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
- print_varobj (child, print_values, 1 /* print expression */);
+ print_varobj (child, print_values, 1 /* print_expression */);
do_cleanups (cleanup_child);
}
do_cleanups (cleanup);
+ VEC_free (varobj_p, r->new);
+ r->new = NULL; /* Paranoia. */
}
-
+
if (mi_version (uiout) > 1)
do_cleanups (cleanup);
}
VEC_free (varobj_update_result, changes);
}
+
+void
+mi_cmd_enable_pretty_printing (char *command, char **argv, int argc)
+{
+ if (argc != 0)
+ error (_("mi_cmd_enable_pretty_printing: no arguments allowed"));
+ varobj_enable_pretty_printing ();
+}
+
+void
+mi_cmd_var_set_update_range (char *command, char **argv, int argc)
+{
+ struct varobj *var;
+ int from, to;
+
+ if (argc != 3)
+ error (_("mi_cmd_var_set_update_range: Usage: VAROBJ FROM TO"));
+
+ var = varobj_get_handle (argv[0]);
+ from = atoi (argv[1]);
+ to = atoi (argv[2]);
+
+ varobj_set_child_range (var, from, to);
+}
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index dd3d803..8ba086c 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -52,6 +52,7 @@ struct mi_cmd mi_cmds[] =
{ "data-write-memory", { NULL, 0 }, mi_cmd_data_write_memory},
{ "data-write-register-values", { NULL, 0 }, mi_cmd_data_write_register_values},
{ "enable-timings", { NULL, 0 }, mi_cmd_enable_timings},
+ { "enable-pretty-printing", { NULL, 0 }, mi_cmd_enable_pretty_printing},
{ "environment-cd", { NULL, 0 }, mi_cmd_env_cd},
{ "environment-directory", { NULL, 0 }, mi_cmd_env_dir},
{ "environment-path", { NULL, 0 }, mi_cmd_env_path},
@@ -112,6 +113,7 @@ struct mi_cmd mi_cmds[] =
{ "var-list-children", { NULL, 0 }, mi_cmd_var_list_children},
{ "var-set-format", { NULL, 0 }, mi_cmd_var_set_format},
{ "var-set-frozen", { NULL, 0 }, mi_cmd_var_set_frozen},
+ { "var-set-update-range", { NULL, 0 }, mi_cmd_var_set_update_range },
{ "var-set-visualizer", { NULL, 0 }, mi_cmd_var_set_visualizer},
{ "var-show-attributes", { NULL, 0 }, mi_cmd_var_show_attributes},
{ "var-show-format", { NULL, 0 }, mi_cmd_var_show_format},
diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h
index 85ad0c4..dfab411 100644
--- a/gdb/mi/mi-cmds.h
+++ b/gdb/mi/mi-cmds.h
@@ -99,6 +99,8 @@ extern mi_cmd_argv_ftype mi_cmd_var_set_visualizer;
extern mi_cmd_argv_ftype mi_cmd_var_show_attributes;
extern mi_cmd_argv_ftype mi_cmd_var_show_format;
extern mi_cmd_argv_ftype mi_cmd_var_update;
+extern mi_cmd_argv_ftype mi_cmd_enable_pretty_printing;
+extern mi_cmd_argv_ftype mi_cmd_var_set_update_range;
/* Description of a single command. */
diff --git a/gdb/testsuite/gdb.mi/gdb701.exp b/gdb/testsuite/gdb.mi/gdb701.exp
index d4acdc2..244c731 100644
--- a/gdb/testsuite/gdb.mi/gdb701.exp
+++ b/gdb/testsuite/gdb.mi/gdb701.exp
@@ -54,7 +54,7 @@ mi_gdb_test "-var-list-children fooPtr" \
foreach i [list x y z] {
mi_gdb_test "-var-list-children fooPtr.$i" \
- "(&\".*\"\r\n)*\\^done,numchild=\"0\"" \
+ "(&\".*\"\r\n)*\\^done,numchild=\"0\",has_more=\"0\"" \
"list children of fooPtr.$i"
}
diff --git a/gdb/testsuite/gdb.mi/mi-break.exp b/gdb/testsuite/gdb.mi/mi-break.exp
index 619727d..8d06c0e 100644
--- a/gdb/testsuite/gdb.mi/mi-break.exp
+++ b/gdb/testsuite/gdb.mi/mi-break.exp
@@ -175,7 +175,7 @@ proc test_error {} {
# containing function call, the internal breakpoint created to handle
# function call would be reported, messing up MI output.
mi_gdb_test "-var-create V * return_1()" \
- "\\^done,name=\"V\",numchild=\"0\",value=\"1\",type=\"int\"" \
+ "\\^done,name=\"V\",numchild=\"0\",value=\"1\",type=\"int\",has_more=\"0\"" \
"create varobj for function call"
mi_gdb_test "-var-update *" \
diff --git a/gdb/testsuite/gdb.mi/mi-var-block.exp b/gdb/testsuite/gdb.mi/mi-var-block.exp
index 8806848..93ded26 100644
--- a/gdb/testsuite/gdb.mi/mi-var-block.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-block.exp
@@ -74,7 +74,7 @@ mi_step_to "do_block_tests" "" "var-cmd.c" \
# Test: c_variable-3.4
# Desc: check foo, cb changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"foo\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"cb\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"foo\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"cb\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: cb foo changed"
# step to "foo = 321;"
diff --git a/gdb/testsuite/gdb.mi/mi-var-child.exp b/gdb/testsuite/gdb.mi/mi-var-child.exp
index 1f4bdc6..eb6c456 100644
--- a/gdb/testsuite/gdb.mi/mi-var-child.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-child.exp
@@ -680,7 +680,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.2
# Desc: check that integer changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.integer\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.integer"
# Step over:
@@ -693,7 +693,7 @@ mi_execute_to "exec-step 3" "end-stepping-range" do_children_tests {} ".*${srcfi
# Test: c_variable-5.3
# Desc: check that char_ptr changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.char_ptr"
# Step over "struct_declarations.int_ptr_ptr = &foo;"
@@ -703,7 +703,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.4
# Desc: check that int_ptr_ptr and children changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars int_ptr_ptr and children changed"
# Step over "weird->long_array[0] = 1234;"
@@ -713,7 +713,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.5
# Desc: check that long_array[0] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.0\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.0\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.0 changed"
# Step over "struct_declarations.long_array[1] = 2345;"
@@ -723,7 +723,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.6
# Desc: check that long_array[1] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.1\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.1\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.1 changed"
# Step over "weird->long_array[2] = 3456;"
@@ -733,7 +733,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.7
# Desc: check that long_array[2] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.2\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.2\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.2 changed"
# Step over:
@@ -752,7 +752,7 @@ mi_execute_to "exec-step 7" "end-stepping-range" do_children_tests {} ".*${srcfi
# Test: c_variable-5.8
# Desc: check that long_array[3-9] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.3\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.4\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.5\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.6\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.7\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.8\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.9\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.3\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.4\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.5\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.6\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.7\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.8\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.9\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.3-9 changed"
@@ -763,7 +763,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.9
# Desc: check that func_ptr changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.func_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.func_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.func_ptr changed"
# Step over "struct_declarations.long_array[10] = 3456";
@@ -771,7 +771,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
[expr $line_dct_nothing + 2] "step \$line_dct_nothing + 2"
mi_gdb_test "-var-update --no-values *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.10\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.10\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.10 changed, don't print values."
# Step over "struct_declarations.long_array[11] = 5678";
@@ -780,7 +780,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
$line_dct_a0_0 "step \$line_dct_a0_0"
mi_gdb_test "-var-update --all-values *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.11\",value=\"5678\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.11\",value=\"5678\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.11 changed, print values."
mi_list_varobj_children {struct_declarations.long_array --all-values} {
@@ -1121,7 +1121,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.47
# Desc: check that psnp->char_ptr (and [0].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr.\\*\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr.\\*\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->char_ptr (and 0.char_ptr) changed"
# Step over "snp1.char_ptr = &c3;"
@@ -1131,7 +1131,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.48
# Desc: check that psnp->next->char_ptr (and [1].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr.\\*\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr.\\*\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->char_ptr (and 1.char_ptr) changed"
@@ -1142,7 +1142,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.49
# Desc: check that psnp->next->next->char_ptr (and [2].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->next->char_ptr (and 2.char_ptr) changed"
@@ -1153,7 +1153,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.50
# Desc: check that psnp->long_ptr (and [0].long_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->long_ptr (and 0.long_ptr) changed"
@@ -1181,7 +1181,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.52
# Desc: check that psnp->next->next->long_ptr (and [2].long_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.long_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->next->long_ptr (and 2.long_ptr) changed"
mi_prepare_inline_tests $srcfile
diff --git a/gdb/testsuite/gdb.mi/mi-var-cmd.exp b/gdb/testsuite/gdb.mi/mi-var-cmd.exp
index ad2e55c..6efb333 100644
--- a/gdb/testsuite/gdb.mi/mi-var-cmd.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-cmd.exp
@@ -146,7 +146,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" $line_dlt_linteger "step at do_local
# Test: c_variable-2.2
# Desc: check whether only linteger changed values
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: linteger changed"
# Step over "lpinteger = &linteger;"
@@ -155,7 +155,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 1] "step
# Test: c_variable-2.3
# Desc: check whether only lpinteger changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpinteger changed"
# Step over "lcharacter = 'a';"
@@ -164,7 +164,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 2] "step
# Test: c_variable-2.4
# Desc: check whether only lcharacter changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lcharacter changed"
# Step over "lpcharacter = &lcharacter;"
@@ -173,7 +173,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 3] "step
# Test: c_variable-2.5
# Desc: check whether only lpcharacter changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpcharacter changed"
@@ -195,7 +195,7 @@ mi_execute_to "exec-step 9" "end-stepping-range" "do_locals_tests" "" \
# Desc: check whether llong, lplong, lfloat, lpfloat, ldouble, lpdouble, lsimple.integer,
# lsimple.unsigned_character lsimple.integer lsimple.character changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpdouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lplong\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpdouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lplong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: many changed"
# Step over:
@@ -212,7 +212,7 @@ mi_execute_to "exec-step 4" "end-stepping-range" "do_locals_tests" "" \
# Test: c_variable-2.7
# Desc: check whether (lsimple.signed_character, lsimple.char_ptr) lpsimple, func changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"func\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpsimple\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"func\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpsimple\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: func and lpsimple changed"
# Step over
@@ -234,7 +234,7 @@ mi_execute_to "exec-step 8" "end-stepping-range" "do_locals_tests" "" \
# Note: this test also checks that lpsimple->integer and lsimple.integer have
# changed (they are the same)
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lsimple and others changed"
@@ -257,7 +257,7 @@ mi_gdb_test "-var-assign linteger 3333" \
# change.
set lpchar_update "\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\},"
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[($lpchar_update)?\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[($lpchar_update)?\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: linteger changed after assign"
mi_gdb_test "-var-assign linteger 3333" \
@@ -277,7 +277,7 @@ mi_gdb_test "-var-assign lpinteger \"&linteger + 3\"" \
"assign to lpinteger"
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpinteger changed after assign"
mi_gdb_test "-var-update *" \
@@ -377,7 +377,7 @@ mi_gdb_test "-var-update *" \
"assign same value to func (update)"
mi_gdb_test "-var-create array_ptr * array_ptr" \
- "\\^done,name=\"array_ptr\",numchild=\"1\",value=\"$hex\",type=\"int \\*\"" \
+ "\\^done,name=\"array_ptr\",numchild=\"1\",value=\"$hex\",type=\"int \\*\",has_more=\"0\"" \
"create global variable array_ptr"
mi_gdb_test "-var-assign array_ptr array2" \
@@ -385,7 +385,7 @@ mi_gdb_test "-var-assign array_ptr array2" \
"assign array to pointer"
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"array_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"array_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"assign array to pointer (update)"
mi_gdb_test "-var-assign array_ptr array2" \
@@ -439,7 +439,7 @@ mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\
# Test: c_variable-2.13
# Desc: change subroutine1 local i
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"i\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"i\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: i changed"
mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\}" \
@@ -448,7 +448,7 @@ mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\
# Test: c_variable-2.14
# Desc: change do_locals_tests local llong
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: llong changed"
set line_dlt_call_subroutine1 [gdb_get_line_number "subroutine1 (linteger, &llong);"]
@@ -458,7 +458,7 @@ mi_next_to "do_locals_tests" "" "var-cmd.c" \
# Test: c_variable-2.15
# Desc: check for out of scope subroutine1 locals
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\,type_changed=\"false\"},\{name=\"i\",in_scope=\"false\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\,type_changed=\"false\",has_more=\"0\"},\{name=\"i\",in_scope=\"false\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: all now out of scope"
# Done with locals/globals tests. Erase all variables
@@ -550,14 +550,14 @@ mi_gdb_test "-var-create selected_a @ a" \
mi_continue_to incr_a
mi_gdb_test "-var-update selected_a" \
- "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"char\",new_num_children=\"0\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"char\",new_num_children=\"0\",has_more=\"0\"\}\\\]" \
"update selected_a in incr_a"
mi_next "step a line in incr_a"
mi_next "return from incr_a to do_special_tests"
mi_gdb_test "-var-update selected_a" \
- "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"int\",new_num_children=\"0\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"int\",new_num_children=\"0\",has_more=\"0\"\}\\\]" \
"update selected_a in do_special_tests"
mi_gdb_test "-file-exec-and-symbols ${binfile}" "\\^done" \
@@ -596,7 +596,7 @@ mi_check_varobj_value F 7 "check F inside callee"
# A varobj we fail to read during -var-update should be considered
# out of scope.
mi_gdb_test "-var-create null_ptr * **0" \
- {\^done,name="null_ptr",numchild="0",value=".*",type="int"} \
+ {\^done,name="null_ptr",numchild="0",value=".*",type="int",has_more="0"} \
"create null_ptr"
# Allow this to succeed, if address zero is readable, although it
@@ -644,7 +644,7 @@ mi_check_varobj_value "L" "{...}" "in-and-out-of-scope: check initial value"
mi_runto main
mi_gdb_test "-var-update L" \
- {\^done,changelist=\[{name="L",in_scope="false",type_changed="false"}\]} \
+ {\^done,changelist=\[{name="L",in_scope="false",type_changed="false",has_more="0"}\]} \
"in-and-out-of-scope: out of scope now"
mi_gdb_test "-var-update L" \
@@ -654,7 +654,7 @@ mi_gdb_test "-var-update L" \
mi_continue_to do_locals_tests
mi_gdb_test "-var-update L" \
- {\^done,changelist=\[{name="L",in_scope="true",type_changed="false"}\]} \
+ {\^done,changelist=\[{name="L",in_scope="true",type_changed="false",has_more="0"}\]} \
"in-and-out-of-scope: in scope now"
mi_gdb_test "-var-update L" \
diff --git a/gdb/testsuite/gdb.mi/mi-var-display.exp b/gdb/testsuite/gdb.mi/mi-var-display.exp
index 4b02e50..faa9172 100644
--- a/gdb/testsuite/gdb.mi/mi-var-display.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-display.exp
@@ -558,7 +558,7 @@ mi_gdb_test "-var-info-num-children e" \
# Test: c_variable-7.55
# Desc: children of e
mi_gdb_test "-var-list-children e" \
- "\\^done,numchild=\"0\"" \
+ "\\^done,numchild=\"0\",has_more=\"0\"" \
"get children of e"
# Test: c_variable-7.60
@@ -600,7 +600,7 @@ mi_gdb_test "-var-info-num-children anone" \
# Test: c_variable-7.75
# Desc: children of anone
mi_gdb_test "-var-list-children anone" \
- "\\^done,numchild=\"0\"" \
+ "\\^done,numchild=\"0\",has_more=\"0\"" \
"get children of anone"
diff --git a/gdb/testsuite/gdb.mi/mi-var-invalidate.exp b/gdb/testsuite/gdb.mi/mi-var-invalidate.exp
index 05d46fa..4b95674 100644
--- a/gdb/testsuite/gdb.mi/mi-var-invalidate.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-invalidate.exp
@@ -72,7 +72,7 @@ mi_runto main
# Check local variable is "invalid".
mi_gdb_test "-var-update linteger" \
- "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"invalid\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"invalid\",has_more=\"0\"\}\\\]" \
"linteger not anymore in scope due to binary changes"
mi_gdb_test "-var-info-type linteger" \
@@ -97,7 +97,7 @@ mi_delete_breakpoints
mi_gdb_load ${binfile2}
# Check local variable are "invalid"
mi_gdb_test "-var-update linteger" \
- "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"invalid\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"invalid\",has_more=\"0\"\}\\\]" \
"linteger not valid anymore due to binary changes"
mi_gdb_test "-var-info-type linteger" \
@@ -106,7 +106,7 @@ mi_gdb_test "-var-info-type linteger" \
# Check global variable are still correct.
mi_gdb_test "-var-update global_simple" \
- "\\^done,changelist=\\\[\{name=\"global_simple\",in_scope=\"invalid\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"global_simple\",in_scope=\"invalid\",has_more=\"0\"\}\\\]" \
"global_simple not anymore in scope due to binary changes"
mi_gdb_test "-var-info-type global_simple" \
diff --git a/gdb/testsuite/gdb.mi/mi2-var-block.exp b/gdb/testsuite/gdb.mi/mi2-var-block.exp
index 6bcfea3..9b3d08f 100644
--- a/gdb/testsuite/gdb.mi/mi2-var-block.exp
+++ b/gdb/testsuite/gdb.mi/mi2-var-block.exp
@@ -74,7 +74,7 @@ mi_step_to "do_block_tests" "" "var-cmd.c" \
# Test: c_variable-3.4
# Desc: check foo, cb changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"foo\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"cb\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"foo\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"cb\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: cb foo changed"
# step to "foo = 321;"
diff --git a/gdb/testsuite/gdb.mi/mi2-var-child.exp b/gdb/testsuite/gdb.mi/mi2-var-child.exp
index 161b34f..0f9b4d4 100644
--- a/gdb/testsuite/gdb.mi/mi2-var-child.exp
+++ b/gdb/testsuite/gdb.mi/mi2-var-child.exp
@@ -1,4 +1,4 @@
-# Copyright 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
+# Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2009 Free Software Foundation
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -680,7 +680,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.2
# Desc: check that integer changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.integer\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.integer"
# Step over:
@@ -693,7 +693,7 @@ mi_execute_to "exec-step 3" "end-stepping-range" do_children_tests {} {.*var-cmd
# Test: c_variable-5.3
# Desc: check that char_ptr changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.char_ptr"
# Step over "struct_declarations.int_ptr_ptr = &foo;"
@@ -703,7 +703,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.4
# Desc: check that int_ptr_ptr and children changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars int_ptr_ptr and children changed"
# Step over "weird->long_array[0] = 1234;"
@@ -713,7 +713,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.5
# Desc: check that long_array[0] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.0\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.0\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.0 changed"
# Step over "struct_declarations.long_array[1] = 2345;"
@@ -723,7 +723,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.6
# Desc: check that long_array[1] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.1\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.1\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.1 changed"
# Step over "weird->long_array[2] = 3456;"
@@ -733,7 +733,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.7
# Desc: check that long_array[2] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.2\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.2\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.2 changed"
# Step over:
@@ -752,7 +752,7 @@ mi_execute_to "exec-step 7" "end-stepping-range" do_children_tests {} {.*var-cmd
# Test: c_variable-5.8
# Desc: check that long_array[3-9] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.3\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.4\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.5\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.6\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.7\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.8\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.9\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.3\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.4\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.5\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.6\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.7\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.8\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.9\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.3-9 changed"
@@ -764,7 +764,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.9
# Desc: check that func_ptr changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.func_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.func_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.func_ptr changed"
# Delete all variables
@@ -1075,7 +1075,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.47
# Desc: check that psnp->char_ptr (and [0].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr.\\*\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr.\\*\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->char_ptr (and 0.char_ptr) changed"
# Step over "snp1.char_ptr = &c3;"
@@ -1085,7 +1085,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.48
# Desc: check that psnp->next->char_ptr (and [1].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr.\\*\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr.\\*\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->char_ptr (and 1.char_ptr) changed"
@@ -1096,7 +1096,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.49
# Desc: check that psnp->next->next->char_ptr (and [2].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->next->char_ptr (and 2.char_ptr) changed"
@@ -1107,7 +1107,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.50
# Desc: check that psnp->long_ptr (and [0].long_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->long_ptr (and 0.long_ptr) changed"
@@ -1120,7 +1120,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Why does this have a FIXME?
setup_xfail *-*-*
mi_gdb_test "-var-update *" \
- "FIXME\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.long_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "FIXME\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->long_ptr (and 1.long_ptr) changed"
clear_xfail *-*-*
@@ -1135,7 +1135,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.52
# Desc: check that psnp->next->next->long_ptr (and [2].long_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.long_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->next->long_ptr (and 2.long_ptr) changed"
diff --git a/gdb/testsuite/gdb.mi/mi2-var-cmd.exp b/gdb/testsuite/gdb.mi/mi2-var-cmd.exp
index dda77bb..e900d14 100644
--- a/gdb/testsuite/gdb.mi/mi2-var-cmd.exp
+++ b/gdb/testsuite/gdb.mi/mi2-var-cmd.exp
@@ -126,11 +126,6 @@ mi_gdb_test "-var-create int * int" \
"&\"Attempt to use a type name as an expression.\\\\n\".*\\^error,msg=\"mi_cmd_var_create: unable to create variable object\"" \
"create int"
-# The number 0 must be an invalid frame address and linteger a local variable.
-mi_gdb_test "-var-create invalidframe 0 linteger" \
- "\\^error,msg=\"Failed to find the specified frame\"" \
- "create variable with invalid FRAME-ADDR"
-
##### #####
# #
@@ -151,7 +146,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" $line_dlt_linteger "step at do_local
# Test: c_variable-2.2
# Desc: check whether only linteger changed values
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: linteger changed"
# Step over "lpinteger = &linteger;"
@@ -160,7 +155,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 1] "step
# Test: c_variable-2.3
# Desc: check whether only lpinteger changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpinteger changed"
# Step over "lcharacter = 'a';"
@@ -169,7 +164,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 2] "step
# Test: c_variable-2.4
# Desc: check whether only lcharacter changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lcharacter changed"
# Step over "lpcharacter = &lcharacter;"
@@ -178,7 +173,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 3] "step
# Test: c_variable-2.5
# Desc: check whether only lpcharacter changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpcharacter changed"
@@ -200,7 +195,7 @@ mi_execute_to "exec-step 9" "end-stepping-range" "do_locals_tests" "" \
# Desc: check whether llong, lplong, lfloat, lpfloat, ldouble, lpdouble, lsimple.integer,
# lsimple.unsigned_character lsimple.integer lsimple.character changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpdouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lplong\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpdouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lplong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: many changed"
# Step over:
@@ -217,7 +212,7 @@ mi_execute_to "exec-step 4" "end-stepping-range" "do_locals_tests" "" \
# Test: c_variable-2.7
# Desc: check whether (lsimple.signed_character, lsimple.char_ptr) lpsimple, func changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"func\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpsimple\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"func\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpsimple\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: func and lpsimple changed"
# Step over
@@ -239,7 +234,7 @@ mi_execute_to "exec-step 8" "end-stepping-range" "do_locals_tests" "" \
# Note: this test also checks that lpsimple->integer and lsimple.integer have
# changed (they are the same)
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lsimple and others changed"
@@ -262,7 +257,7 @@ mi_gdb_test "-var-assign linteger 3333" \
# change.
set lpchar_update "\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\},"
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[($lpchar_update)?\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[($lpchar_update)?\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: linteger changed after assign"
mi_gdb_test "-var-assign linteger 3333" \
@@ -282,7 +277,7 @@ mi_gdb_test "-var-assign lpinteger \"&linteger + 3\"" \
"assign to lpinteger"
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpinteger changed after assign"
mi_gdb_test "-var-update *" \
@@ -407,7 +402,7 @@ mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\
# Test: c_variable-2.13
# Desc: change subroutine1 local i
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"i\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"i\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: i changed"
mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\}" \
@@ -416,7 +411,7 @@ mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\
# Test: c_variable-2.14
# Desc: change do_locals_tests local llong
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: llong changed"
set line_dlt_call_subroutine1 [gdb_get_line_number "subroutine1 (linteger, &llong);"]
@@ -426,7 +421,7 @@ mi_next_to "do_locals_tests" "" "var-cmd.c" \
# Test: c_variable-2.15
# Desc: check for out of scope subroutine1 locals
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\,type_changed=\"false\"},\{name=\"i\",in_scope=\"false\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\,type_changed=\"false\",has_more=\"0\"},\{name=\"i\",in_scope=\"false\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: all now out of scope"
# Done with locals/globals tests. Erase all variables
@@ -518,14 +513,14 @@ mi_gdb_test "-var-create selected_a @ a" \
mi_continue_to incr_a
mi_gdb_test "-var-update selected_a" \
- "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"char\",new_num_children=\"0\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"char\",new_num_children=\"0\"\,has_more=\"0\"}\\\]" \
"update selected_a in incr_a"
mi_next "step a line in incr_a"
mi_next "return from incr_a to do_special_tests"
mi_gdb_test "-var-update selected_a" \
- "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"int\",new_num_children=\"0\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"int\",new_num_children=\"0\",has_more=\"0\"\}\\\]" \
"update selected_a in do_special_tests"
mi_gdb_test "-file-exec-and-symbols ${binfile}" "\\^done" \
diff --git a/gdb/testsuite/gdb.mi/mi2-var-display.exp b/gdb/testsuite/gdb.mi/mi2-var-display.exp
index d6ce673..17e208a 100644
--- a/gdb/testsuite/gdb.mi/mi2-var-display.exp
+++ b/gdb/testsuite/gdb.mi/mi2-var-display.exp
@@ -557,7 +557,7 @@ mi_gdb_test "-var-info-num-children e" \
# Test: c_variable-7.55
# Desc: children of e
mi_gdb_test "-var-list-children e" \
- "\\^done,numchild=\"0\"" \
+ "\\^done,numchild=\"0\",has_more=\"0\"" \
"get children of e"
# Test: c_variable-7.60
@@ -599,7 +599,7 @@ mi_gdb_test "-var-info-num-children anone" \
# Test: c_variable-7.75
# Desc: children of anone
mi_gdb_test "-var-list-children anone" \
- "\\^done,numchild=\"0\"" \
+ "\\^done,numchild=\"0\",has_more=\"0\"" \
"get children of anone"
diff --git a/gdb/testsuite/gdb.python/py-mi.exp b/gdb/testsuite/gdb.python/py-mi.exp
index d3f44b2..30d6f32 100644
--- a/gdb/testsuite/gdb.python/py-mi.exp
+++ b/gdb/testsuite/gdb.python/py-mi.exp
@@ -48,23 +48,53 @@ mi_gdb_test "python execfile ('${srcdir}/${subdir}/${testfile}.py')" ""
mi_continue_to_line [gdb_get_line_number {MI breakpoint here} ${testfile}.c] \
"step to breakpoint"
-mi_create_floating_varobj container c "create container varobj"
+mi_create_dynamic_varobj container c \
+ "create container varobj, no pretty-printing"
+
+mi_list_varobj_children container {
+ { container.name name 1 string }
+ { container.len len 0 int }
+ { container.elements elements 1 "int ." }
+} "examine container children=0, no pretty-printing"
+
+mi_delete_varobj container "delete varobj"
+
+mi_gdb_test "-enable-pretty-printing" ""
+
+mi_create_varobj_checked string string_1 \
+ "struct string_repr" \
+ "create string_1 varobj"
+
+mi_gdb_test "-data-evaluate-expression \"string_1 = string_2\"" ".*" \
+ "assign string_1 from string_2"
+
+mi_gdb_test "-var-update string" \
+ "\\^done,changelist=\\\[{name=\"string\",in_scope=\"true\",type_changed=\"false\",dynamic=\"1\",has_more=\"0\"}\\\]" \
+ "update string varobj after assignment"
+
+mi_create_dynamic_varobj container c \
+ "create container varobj"
mi_list_varobj_children container {
} "examine container children=0"
mi_next "next over update 1"
-mi_varobj_update_dynamic container {
- { {container.\[0\]} {\[0\]} 0 int }
-} "varobj update 1"
+mi_varobj_update_dynamic container "varobj update 1" {
+ type_changed false new_num_children 1 dynamic 1 has_more 0
+} {
+} {
+ { name {container.\[0\]} exp {\[0\]} numchild 0 type int thread-id 1 }
+}
mi_next "next over update 2"
-mi_varobj_update_dynamic container {
- { {container.\[0\]} {\[0\]} 0 int }
- { {container.\[1\]} {\[1\]} 0 int }
-} "varobj update 2"
+mi_varobj_update_dynamic container "varobj update 2" {
+ type_changed false new_num_children 2 dynamic 1 has_more 0
+} {
+} {
+ { name {container.\[1\]} exp {\[1\]} numchild 0 type int thread-id 1 }
+}
mi_gdb_test "-var-set-visualizer container None" \
"\\^done" \
@@ -78,19 +108,124 @@ mi_gdb_test "-var-set-visualizer container gdb.default_visualizer" \
"\\^done" \
"choose default visualizer"
-mi_varobj_update_dynamic container {
- { {container.\[0\]} {\[0\]} 0 int }
- { {container.\[1\]} {\[1\]} 0 int }
-} "varobj update after choosing default"
+mi_varobj_update_dynamic container "varobj update after choosing default" {
+ type_changed false new_num_children 2 dynamic 1 has_more 0
+} {
+} {
+ { name {container.\[0\]} exp {\[0\]} numchild 0 type int thread-id 1 }
+ { name {container.\[1\]} exp {\[1\]} numchild 0 type int thread-id 1 }
+}
mi_gdb_test "-var-set-visualizer container ContainerPrinter" \
"\\^done" \
"choose visualizer using expression"
-mi_varobj_update_dynamic container {
+mi_varobj_update_dynamic container \
+ "varobj update after choosing via expression" {
+ type_changed false new_num_children 2 dynamic 1 has_more 0
+ } {
+ } {
+ { name {container.\[0\]} exp {\[0\]} numchild 0 type int thread-id 1 }
+ { name {container.\[1\]} exp {\[1\]} numchild 0 type int thread-id 1 }
+ }
+
+mi_list_varobj_children_range container 1 2 2 {
+ { {container.\[1\]} {\[1\]} 0 int }
+} "list varobj children after selecting child range"
+
+mi_list_varobj_children_range container -1 -1 2 {
{ {container.\[0\]} {\[0\]} 0 int }
{ {container.\[1\]} {\[1\]} 0 int }
-} "varobj update after choosing via expression"
+} "list varobj children after resetting child range"
+
+mi_next "next over update 3"
+
+mi_gdb_test "-var-set-update-range container 0 1" \
+ "\\^done" \
+ "set update range"
+
+# This should truncate the list.
+mi_list_varobj_children container {
+ { {container.\[0\]} {\[0\]} 0 int }
+} "list children after setting update range"
+
+# This should return just the items in [1,2).
+mi_list_varobj_children_range container 1 2 2 {
+ { {container.\[1\]} {\[1\]} 0 int }
+} "list selected children after setting range"
+
+# This should not be affected by the previous list-children request.
+mi_list_varobj_children container {
+ { {container.\[0\]} {\[0\]} 0 int }
+} "list children after listing selected range"
+
+mi_next "next over update 4"
+
+# This should only show the first child, because the update range has
+# been set.
+mi_varobj_update_dynamic container \
+ "update after next with restricted range" {
+ type_changed false new_num_children 1 dynamic 1 has_more 1
+ } {
+ { name {container.\[0\]} in_scope true type_changed false dynamic 1 has_more 0 }
+ } {
+ }
+
+mi_gdb_test "-var-set-update-range container 3 4" \
+ "\\^done" \
+ "set update range with non-zero start"
+
+# Elements were updated but should not be reported.
+mi_varobj_update_dynamic container \
+ "update varobj with change outside selected range" {
+ type_changed false new_num_children 3 dynamic 1 has_more 0
+ } {
+ } {
+ }
+
+mi_next "next over update 5"
+
+# Regression test: examine an object that has no children, then update
+# it to ensure that we don't print the children.
+mi_create_dynamic_varobj container2 c2 \
+ "create second container varobj"
+
+mi_gdb_test "-var-update container2" \
+ "\\^done,changelist=.." \
+ "update varobj, no children requested"
+
+mi_next "next over update 6"
+
+# Now container2 has an element -- and an update should mention that
+# it has_more. But, because we did not request children, we still
+# should not actually see them.
+mi_varobj_update_dynamic container2 \
+ "update varobj 2, no children requested" {
+ type_changed false dynamic 1 has_more 1
+ } {} {}
+
+mi_continue_to_line \
+ [gdb_get_line_number {MI outer breakpoint here} ${testfile}.c] \
+ "step to outer breakpoint"
+
+mi_create_dynamic_varobj outer outer \
+ "create outer varobj"
+
+mi_list_varobj_children outer {
+ { outer.s s 2 "struct substruct" }
+ { outer.x x 0 "int" }
+} "list children of outer"
+
+mi_list_varobj_children outer.s {
+ { outer.s.a a 0 int }
+ { outer.s.b b 0 int }
+} "list children of outer.s"
+
+mi_next "next over outer update"
+
+mi_gdb_test "-var-update outer" \
+ ".done,changelist=.{name=\"outer.s.a\",in_scope=\"true\",type_changed=\"false\",dynamic=\"1\",has_more=\"0\"}." \
+ "update after updating element of outer"
mi_continue_to_line \
[gdb_get_line_number {Another MI breakpoint} ${testfile}.c] \
diff --git a/gdb/testsuite/gdb.python/py-prettyprint.c b/gdb/testsuite/gdb.python/py-prettyprint.c
index 3cafc48..7f16400 100644
--- a/gdb/testsuite/gdb.python/py-prettyprint.c
+++ b/gdb/testsuite/gdb.python/py-prettyprint.c
@@ -15,6 +15,8 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
+#include <string.h>
+
struct s
{
int a;
@@ -80,6 +82,29 @@ class Derived : public Vbase1, public Vbase2, public Vbase3
#endif
+struct substruct {
+ int a;
+ int b;
+};
+
+struct outerstruct {
+ struct substruct s;
+ int x;
+};
+
+struct outerstruct
+substruct_test (void)
+{
+ struct outerstruct outer;
+ outer.s.a = 0;
+ outer.s.b = 0;
+ outer.x = 0;
+
+ outer.s.a = 3; /* MI outer breakpoint here */
+
+ return outer;
+}
+
typedef struct string_repr
{
struct whybother
@@ -148,6 +173,14 @@ void do_nothing(void)
c = 23; /* Another MI breakpoint */
}
+struct nullstr
+{
+ char *s;
+};
+
+struct string_repr string_1 = { { "one" } };
+struct string_repr string_2 = { { "two" } };
+
int
main ()
{
@@ -155,11 +188,15 @@ main ()
struct ss ssa[2];
string x = make_string ("this is x");
zzz_type c = make_container ("container");
+ zzz_type c2 = make_container ("container2");
const struct string_repr cstring = { { "const string" } };
+ /* Clearing by being `static' could invoke an other GDB C++ bug. */
+ struct nullstr nullstr;
init_ss(&ss, 1, 2);
init_ss(ssa+0, 3, 4);
init_ss(ssa+1, 5, 6);
+ memset (&nullstr, 0, sizeof nullstr);
struct ns ns;
ns.null_str = "embedded\0null\0string";
@@ -193,6 +230,14 @@ main ()
add_item (&c, 72);
#ifdef MI
+ add_item (&c, 1011);
+ c.elements[0] = 1023;
+ c.elements[0] = 2323;
+
+ add_item (&c2, 2222);
+ add_item (&c2, 3333);
+
+ substruct_test ();
do_nothing ();
#endif
diff --git a/gdb/testsuite/gdb.python/py-prettyprint.py b/gdb/testsuite/gdb.python/py-prettyprint.py
index bf009a1..2f070d8 100644
--- a/gdb/testsuite/gdb.python/py-prettyprint.py
+++ b/gdb/testsuite/gdb.python/py-prettyprint.py
@@ -92,6 +92,13 @@ class pp_vbase1:
def to_string (self):
return "pp class name: " + self.val.type.tag
+class pp_nullstr:
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ return self.val['s'].string(gdb.parameter('target-charset'))
+
class pp_ns:
"Print a std::basic_string of some kind"
@@ -105,11 +112,24 @@ class pp_ns:
def display_hint (self):
return 'string'
+class pp_outer:
+ "Print struct outer"
+
+ def __init__ (self, val):
+ self.val = val
+
+ def to_string (self):
+ return "x = %s" % self.val['x']
+
+ def children (self):
+ yield 's', self.val['s']
+ yield 'x', self.val['x']
+
def lookup_function (val):
"Look-up and return a pretty-printer that can print val."
# Get the type.
- type = val.type;
+ type = val.type
# If it points to a reference, get the reference.
if type.code == gdb.TYPE_CODE_REF:
@@ -148,6 +168,9 @@ def register_pretty_printers ():
pretty_printers_dict[re.compile ('^VirtualTest$')] = pp_multiple_virtual
pretty_printers_dict[re.compile ('^Vbase1$')] = pp_vbase1
+
+ pretty_printers_dict[re.compile ('^struct nullstr$')] = pp_nullstr
+ pretty_printers_dict[re.compile ('^nullstr$')] = pp_nullstr
# Note that we purposely omit the typedef names here.
# Printer lookup is based on canonical name.
@@ -160,6 +183,10 @@ def register_pretty_printers ():
pretty_printers_dict[re.compile ('^struct ns$')] = pp_ns
pretty_printers_dict[re.compile ('^ns$')] = pp_ns
+
+ pretty_printers_dict[re.compile ('^struct outerstruct$')] = pp_outer
+ pretty_printers_dict[re.compile ('^outerstruct$')] = pp_outer
+
pretty_printers_dict = {}
register_pretty_printers ()
diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
index e691232..167a02c 100644
--- a/gdb/testsuite/lib/mi-support.exp
+++ b/gdb/testsuite/lib/mi-support.exp
@@ -1195,13 +1195,13 @@ proc mi_list_breakpoints { expected test } {
# Name cannot be "-".
proc mi_create_varobj { name expression testname } {
mi_gdb_test "-var-create $name * $expression" \
- "\\^done,name=\"$name\",numchild=\"\[0-9\]+\",value=\".*\",type=.*" \
+ "\\^done,name=\"$name\",numchild=\"\[0-9\]+\",value=\".*\",type=.*,has_more=\"0\"" \
$testname
}
proc mi_create_floating_varobj { name expression testname } {
mi_gdb_test "-var-create $name @ $expression" \
- "\\^done,name=\"$name\",numchild=\"\[0-9\]+\",value=\".*\",type=.*" \
+ "\\^done,name=\"$name\",numchild=\"\(-1\|\[0-9\]+\)\",value=\".*\",type=.*" \
$testname
}
@@ -1214,6 +1214,14 @@ proc mi_create_varobj_checked { name expression type testname } {
$testname
}
+# Same as mi_create_floating_varobj, but assumes the test is creating
+# a dynamic varobj that has children, so the value must be "{...}".
+proc mi_create_dynamic_varobj {name expression testname} {
+ mi_gdb_test "-var-create $name @ $expression" \
+ "\\^done,name=\"$name\",numchild=\"\(-1\|\[0-9\]+\)\",value=\"{\\.\\.\\.}\",type=.*" \
+ $testname
+}
+
# Deletes the specified NAME.
proc mi_delete_varobj { name testname } {
mi_gdb_test "-var-delete $name" \
@@ -1229,7 +1237,7 @@ proc mi_varobj_update { name expected testname } {
set er "\\^done,changelist=\\\["
set first 1
foreach item $expected {
- set v "{name=\"$item\",in_scope=\"true\",type_changed=\"false\"}"
+ set v "{name=\"$item\",in_scope=\"true\",type_changed=\"false\",has_more=\".\"}"
if {$first == 1} {
set er "$er$v"
set first 0
@@ -1244,22 +1252,70 @@ proc mi_varobj_update { name expected testname } {
}
proc mi_varobj_update_with_type_change { name new_type new_children testname } {
- set v "{name=\"$name\",in_scope=\"true\",type_changed=\"true\",new_type=\"$new_type\",new_num_children=\"$new_children\"}"
+ set v "{name=\"$name\",in_scope=\"true\",type_changed=\"true\",new_type=\"$new_type\",new_num_children=\"$new_children\",has_more=\".\"}"
set er "\\^done,changelist=\\\[$v\\\]"
verbose -log "Expecting: $er"
mi_gdb_test "-var-update $name" $er $testname
}
-# Update a dynamic varobj named NAME. CHILDREN is a list of children,
-# in the same form as mi_list_varobj_children. TESTNAME is the name
-# of the test.
-proc mi_varobj_update_dynamic {name children testname} {
- set children_exp_j [mi_child_regexp $children 0]
+# A helper that turns a key/value list into a regular expression
+# matching some MI output.
+proc mi_varobj_update_kv_helper {list} {
+ set first 1
+ set rx ""
+ foreach {key value} $list {
+ if {!$first} {
+ append rx ,
+ }
+ set first 0
+ if {$key == "new_children"} {
+ append rx "$key=\\\[$value\\\]"
+ } else {
+ append rx "$key=\"$value\""
+ }
+ }
+ return $rx
+}
- set er "\\^done,changelist=\\\["
+# A helper for mi_varobj_update_dynamic that computes a match
+# expression given a child list.
+proc mi_varobj_update_dynamic_helper {children} {
+ set crx ""
- append er "{name=\"$name\",in_scope=\"true\",type_changed=\"false\""
- append er ",children=\\\[$children_exp_j.*\\\]}\\\]"
+ set first 1
+ foreach child $children {
+ if {!$first} {
+ append crx ,
+ }
+ set first 0
+ append crx "{"
+ append crx [mi_varobj_update_kv_helper $child]
+ append crx "}"
+ }
+
+ return $crx
+}
+
+# Update a dynamic varobj named NAME. CHILDREN is a list of children
+# that have been updated; NEW_CHILDREN is a list of children that were
+# added to the primary varobj. Each child is a list of key/value
+# pairs that are expected. SELF is a key/value list holding
+# information about the varobj itself. TESTNAME is the name of the
+# test.
+proc mi_varobj_update_dynamic {name testname self children new_children} {
+ if {[llength $new_children]} {
+ set newrx [mi_varobj_update_dynamic_helper $new_children]
+ lappend self new_children $newrx
+ }
+ set selfrx [mi_varobj_update_kv_helper $self]
+ set crx [mi_varobj_update_dynamic_helper $children]
+
+ set er "\\^done,changelist=\\\[\{name=\"$name\",in_scope=\"true\""
+ append er ",$selfrx\}"
+ if {"$crx" != ""} {
+ append er ",$crx"
+ }
+ append er "\\\]"
verbose -log "Expecting: $er"
mi_gdb_test "-var-update $name" $er $testname
@@ -1329,14 +1385,13 @@ proc mi_child_regexp {children add_child} {
# have no value.
#
proc mi_list_varobj_children { varname children testname } {
- mi_list_varobj_children_range $varname [llength $children] $children \
+ mi_list_varobj_children_range $varname "" "" [llength $children] $children \
$testname
}
-# Like mi_list_varobj_children, but assumes that a subrange has been
-# selected with -var-set-child-range. NUMCHILDREN is the total number
-# of children.
-proc mi_list_varobj_children_range {varname numchildren children testname} {
+# Like mi_list_varobj_children, but sets a subrange. NUMCHILDREN is
+# the total number of children.
+proc mi_list_varobj_children_range {varname from to numchildren children testname} {
set options ""
if {[llength $varname] == 2} {
set options [lindex $varname 1]
@@ -1352,9 +1407,18 @@ proc mi_list_varobj_children_range {varname numchildren children testname} {
set expected "\\^done,numchild=\"0\""
}
+ if {"$to" == ""} {
+ append expected ",has_more=\"0\""
+ } elseif {$to >= 0 && $numchildren > $to} {
+ append expected ",has_more=\"1\""
+ } else {
+ append expected ",has_more=\"0\""
+ }
+
verbose -log "Expecting: $expected"
- mi_gdb_test "-var-list-children $options $varname" $expected $testname
+ mi_gdb_test "-var-list-children $options $varname $from $to" \
+ $expected $testname
}
# Verifies that variable object VARNAME has NUMBER children,
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 603071f..e7fb589 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -29,6 +29,7 @@
#include "gdb_assert.h"
#include "gdb_string.h"
+#include "gdb_regex.h"
#include "varobj.h"
#include "vec.h"
@@ -59,6 +60,15 @@ char *varobj_format_string[] =
/* String representations of gdb's known languages */
char *varobj_language_string[] = { "unknown", "C", "C++", "Java" };
+/* True if we want to allow Python-based pretty-printing. */
+static int pretty_printing = 0;
+
+void
+varobj_enable_pretty_printing (void)
+{
+ pretty_printing = 1;
+}
+
/* Data structures */
/* Every root variable has one of these structures saved in its
@@ -173,9 +183,31 @@ struct varobj
frozen. */
int not_fetched;
+ /* Sub-range of children which the MI consumer has requested. If
+ FROM < 0 or TO < 0, means that all children have been
+ requested. */
+ int from;
+ int to;
+
+ /* The pretty-printer constructor. If NULL, then the default
+ pretty-printer will be looked up. If None, then no
+ pretty-printer will be installed. */
+ PyObject *constructor;
+
/* The pretty-printer that has been constructed. If NULL, then a
new printer object is needed, and one will be constructed. */
PyObject *pretty_printer;
+
+ /* The iterator returned by the printer's 'children' method, or NULL
+ if not available. */
+ PyObject *child_iter;
+
+ /* We request one extra item from the iterator, so that we can
+ report to the caller whether there are more items than we have
+ already reported. However, we don't want to install this value
+ when we read it, because that will mess up future updates. So,
+ we stash it here instead. */
+ PyObject *saved_item;
};
struct cpstack
@@ -236,8 +268,6 @@ static char *cppop (struct cpstack **pstack);
static int install_new_value (struct varobj *var, struct value *value,
int initial);
-static void install_default_visualizer (struct varobj *var);
-
/* Language-specific routines. */
static enum varobj_languages variable_language (struct varobj *var);
@@ -623,7 +653,6 @@ varobj_create (char *objname,
}
}
- install_default_visualizer (var);
discard_cleanups (old_chain);
return var;
}
@@ -738,15 +767,8 @@ instantiate_pretty_printer (PyObject *constructor, struct value *value)
#if HAVE_PYTHON
PyObject *val_obj = NULL;
PyObject *printer;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- value = value_copy (value);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
val_obj = value_to_value_object (value);
-
if (! val_obj)
return NULL;
@@ -810,6 +832,17 @@ varobj_get_display_hint (struct varobj *var)
return result;
}
+/* Return true if the varobj has items after TO, false otherwise. */
+
+int
+varobj_has_more (struct varobj *var, int to)
+{
+ if (VEC_length (varobj_p, var->children) > to)
+ return 1;
+ return ((to == -1 || VEC_length (varobj_p, var->children) == to)
+ && var->saved_item != NULL);
+}
+
/* If the variable object is bound to a specific thread, that
is its evaluation can always be done in context of a frame
inside that thread, returns GDB id of the thread -- which
@@ -842,22 +875,97 @@ varobj_get_frozen (struct varobj *var)
return var->frozen;
}
+/* A helper function that restricts a range to what is actually
+ available in a VEC. This follows the usual rules for the meaning
+ of FROM and TO -- if either is negative, the entire range is
+ used. */
+
+static void
+restrict_range (VEC (varobj_p) *children, int *from, int *to)
+{
+ if (*from < 0 || *to < 0)
+ {
+ *from = 0;
+ *to = VEC_length (varobj_p, children);
+ }
+ else
+ {
+ if (*from > VEC_length (varobj_p, children))
+ *from = VEC_length (varobj_p, children);
+ if (*to > VEC_length (varobj_p, children))
+ *to = VEC_length (varobj_p, children);
+ if (*from > *to)
+ *from = *to;
+ }
+}
+
+/* A helper for update_dynamic_varobj_children that installs a new
+ child when needed. */
+
+static void
+install_dynamic_child (struct varobj *var,
+ VEC (varobj_p) **changed,
+ VEC (varobj_p) **new,
+ VEC (varobj_p) **unchanged,
+ int *cchanged,
+ int index,
+ const char *name,
+ struct value *value)
+{
+ if (VEC_length (varobj_p, var->children) < index + 1)
+ {
+ /* There's no child yet. */
+ struct varobj *child = varobj_add_child (var, name, value);
+ if (new)
+ {
+ VEC_safe_push (varobj_p, *new, child);
+ *cchanged = 1;
+ }
+ }
+ else
+ {
+ varobj_p existing = VEC_index (varobj_p, var->children, index);
+ if (install_new_value (existing, value, 0))
+ {
+ if (changed)
+ VEC_safe_push (varobj_p, *changed, existing);
+ }
+ else if (unchanged)
+ VEC_safe_push (varobj_p, *unchanged, existing);
+ }
+}
+
+#if HAVE_PYTHON
+
+static int
+dynamic_varobj_has_child_method (struct varobj *var)
+{
+ struct cleanup *back_to;
+ PyObject *printer = var->pretty_printer;
+ int result;
+
+ back_to = varobj_ensure_python_env (var);
+ result = PyObject_HasAttr (printer, gdbpy_children_cst);
+ do_cleanups (back_to);
+ return result;
+}
+
+#endif
+
static int
update_dynamic_varobj_children (struct varobj *var,
VEC (varobj_p) **changed,
- VEC (varobj_p) **new_and_unchanged,
- int *cchanged)
-
+ VEC (varobj_p) **new,
+ VEC (varobj_p) **unchanged,
+ int *cchanged,
+ int update_children,
+ int from,
+ int to)
{
#if HAVE_PYTHON
- /* FIXME: we *might* want to provide this functionality as
- a standalone function, so that other interested parties
- than varobj code can benefit for this. */
struct cleanup *back_to;
PyObject *children;
- PyObject *iterator;
int i;
- int children_changed = 0;
PyObject *printer = var->pretty_printer;
back_to = varobj_ensure_python_env (var);
@@ -869,87 +977,106 @@ update_dynamic_varobj_children (struct varobj *var,
return 0;
}
- children = PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
- NULL);
-
- if (!children)
+ if (update_children || !var->child_iter)
{
- gdbpy_print_stack ();
- error (_("Null value returned for children"));
- }
+ children = PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
+ NULL);
+
+ if (!children)
+ {
+ gdbpy_print_stack ();
+ error (_("Null value returned for children"));
+ }
- make_cleanup_py_decref (children);
+ make_cleanup_py_decref (children);
- if (!PyIter_Check (children))
- error (_("Returned value is not iterable"));
+ if (!PyIter_Check (children))
+ error (_("Returned value is not iterable"));
- iterator = PyObject_GetIter (children);
- if (!iterator)
- {
- gdbpy_print_stack ();
- error (_("Could not get children iterator"));
+ Py_XDECREF (var->child_iter);
+ var->child_iter = PyObject_GetIter (children);
+ if (!var->child_iter)
+ {
+ gdbpy_print_stack ();
+ error (_("Could not get children iterator"));
+ }
+
+ Py_XDECREF (var->saved_item);
+ var->saved_item = NULL;
+
+ i = 0;
}
- make_cleanup_py_decref (iterator);
+ else
+ i = VEC_length (varobj_p, var->children);
- for (i = 0; ; ++i)
+ /* We ask for one extra child, so that MI can report whether there
+ are more children. */
+ for (; to < 0 || i < to + 1; ++i)
{
- PyObject *item = PyIter_Next (iterator);
- PyObject *py_v;
- struct value *v;
- char *name;
- struct cleanup *inner;
-
- if (!item)
- break;
- inner = make_cleanup_py_decref (item);
+ PyObject *item;
- if (!PyArg_ParseTuple (item, "sO", &name, &py_v))
- error (_("Invalid item from the child list"));
-
- v = convert_value_from_python (py_v);
+ /* See if there was a leftover from last time. */
+ if (var->saved_item)
+ {
+ item = var->saved_item;
+ var->saved_item = NULL;
+ }
+ else
+ item = PyIter_Next (var->child_iter);
- /* TODO: This assume the name of the i-th child never changes. */
+ if (!item)
+ break;
- /* Now see what to do here. */
- if (VEC_length (varobj_p, var->children) < i + 1)
+ /* We don't want to push the extra child on any report list. */
+ if (to < 0 || i < to)
{
- /* There's no child yet. */
- struct varobj *child = varobj_add_child (var, name, v);
- if (new_and_unchanged)
- VEC_safe_push (varobj_p, *new_and_unchanged, child);
- children_changed = 1;
+ PyObject *py_v;
+ char *name;
+ struct value *v;
+ struct cleanup *inner;
+ int can_mention = from < 0 || i >= from;
+
+ inner = make_cleanup_py_decref (item);
+
+ if (!PyArg_ParseTuple (item, "sO", &name, &py_v))
+ error (_("Invalid item from the child list"));
+
+ v = convert_value_from_python (py_v);
+ install_dynamic_child (var, can_mention ? changed : NULL,
+ can_mention ? new : NULL,
+ can_mention ? unchanged : NULL,
+ can_mention ? cchanged : NULL, i, name, v);
+ do_cleanups (inner);
}
- else
+ else
{
- varobj_p existing = VEC_index (varobj_p, var->children, i);
- if (install_new_value (existing, v, 0) && changed)
- {
- if (changed)
- VEC_safe_push (varobj_p, *changed, existing);
- }
- else
- {
- if (new_and_unchanged)
- VEC_safe_push (varobj_p, *new_and_unchanged, existing);
- }
- }
+ Py_XDECREF (var->saved_item);
+ var->saved_item = item;
- do_cleanups (inner);
+ /* We want to truncate the child list just before this
+ element. */
+ break;
+ }
}
if (i < VEC_length (varobj_p, var->children))
{
- int i;
- children_changed = 1;
- for (i = 0; i < VEC_length (varobj_p, var->children); ++i)
- varobj_delete (VEC_index (varobj_p, var->children, i), NULL, 0);
+ int j;
+ *cchanged = 1;
+ for (j = i; j < VEC_length (varobj_p, var->children); ++j)
+ varobj_delete (VEC_index (varobj_p, var->children, j), NULL, 0);
+ VEC_truncate (varobj_p, var->children, i);
}
- VEC_truncate (varobj_p, var->children, i);
+
+ /* If there are fewer children than requested, note that the list of
+ children changed. */
+ if (to >= 0 && VEC_length (varobj_p, var->children) < to)
+ *cchanged = 1;
+
var->num_children = VEC_length (varobj_p, var->children);
do_cleanups (back_to);
- *cchanged = children_changed;
return 1;
#else
gdb_assert (0 && "should never be called if Python is not enabled");
@@ -961,20 +1088,27 @@ varobj_get_num_children (struct varobj *var)
{
if (var->num_children == -1)
{
- int changed;
- if (!var->pretty_printer
- || !update_dynamic_varobj_children (var, NULL, NULL, &changed))
+ if (var->pretty_printer)
+ {
+ int dummy;
+
+ /* If we have a dynamic varobj, don't report -1 children.
+ So, try to fetch some children first. */
+ update_dynamic_varobj_children (var, NULL, NULL, NULL, &dummy,
+ 0, 0, 0);
+ }
+ else
var->num_children = number_of_children (var);
}
- return var->num_children;
+ return var->num_children >= 0 ? var->num_children : 0;
}
/* Creates a list of the immediate children of a variable object;
the return code is the number of such children or -1 on error */
VEC (varobj_p)*
-varobj_list_children (struct varobj *var)
+varobj_list_children (struct varobj *var, int *from, int *to)
{
struct varobj *child;
char *name;
@@ -982,12 +1116,16 @@ varobj_list_children (struct varobj *var)
var->children_requested = 1;
- if (var->pretty_printer
+ if (var->pretty_printer)
+ {
/* This, in theory, can result in the number of children changing without
frontend noticing. But well, calling -var-list-children on the same
varobj twice is not something a sane frontend would do. */
- && update_dynamic_varobj_children (var, NULL, NULL, &children_changed))
- return var->children;
+ update_dynamic_varobj_children (var, NULL, NULL, NULL, &children_changed,
+ 0, 0, *to);
+ restrict_range (var->children, from, to);
+ return var->children;
+ }
if (var->num_children == -1)
var->num_children = number_of_children (var);
@@ -1013,10 +1151,10 @@ varobj_list_children (struct varobj *var)
name = name_of_child (var, i);
existing = create_child (var, i, name);
VEC_replace (varobj_p, var->children, i, existing);
- install_default_visualizer (existing);
}
}
+ restrict_range (var->children, from, to);
return var->children;
}
@@ -1027,7 +1165,6 @@ varobj_add_child (struct varobj *var, const char *name, struct value *value)
VEC_length (varobj_p, var->children),
name, value);
VEC_safe_push (varobj_p, var->children, v);
- install_default_visualizer (v);
return v;
}
@@ -1089,6 +1226,12 @@ varobj_get_attributes (struct varobj *var)
return attributes;
}
+int
+varobj_pretty_printed_p (struct varobj *var)
+{
+ return var->pretty_printer != NULL;
+}
+
char *
varobj_get_formatted_value (struct varobj *var,
enum varobj_display_formats format)
@@ -1166,6 +1309,116 @@ varobj_set_value (struct varobj *var, char *expression)
return 1;
}
+#if HAVE_PYTHON
+
+/* A helper function to install a constructor function and visualizer
+ in a varobj. */
+
+static void
+install_visualizer (struct varobj *var, PyObject *constructor,
+ PyObject *visualizer)
+{
+ Py_XDECREF (var->constructor);
+ var->constructor = constructor;
+
+ Py_XDECREF (var->pretty_printer);
+ var->pretty_printer = visualizer;
+
+ Py_XDECREF (var->child_iter);
+ var->child_iter = NULL;
+}
+
+/* Install the default visualizer for VAR. */
+
+static void
+install_default_visualizer (struct varobj *var)
+{
+ if (pretty_printing)
+ {
+ PyObject *pretty_printer = NULL;
+
+ if (var->value)
+ {
+ pretty_printer = gdbpy_get_varobj_pretty_printer (var->value);
+ if (! pretty_printer)
+ {
+ gdbpy_print_stack ();
+ error (_("Cannot instantiate printer for default visualizer"));
+ }
+ }
+
+ if (pretty_printer == Py_None)
+ {
+ Py_DECREF (pretty_printer);
+ pretty_printer = NULL;
+ }
+
+ install_visualizer (var, NULL, pretty_printer);
+ }
+}
+
+/* Instantiate and install a visualizer for VAR using CONSTRUCTOR to
+ make a new object. */
+
+static void
+construct_visualizer (struct varobj *var, PyObject *constructor)
+{
+ PyObject *pretty_printer;
+
+ Py_INCREF (constructor);
+ if (constructor == Py_None)
+ pretty_printer = NULL;
+ else
+ {
+ pretty_printer = instantiate_pretty_printer (constructor, var->value);
+ if (! pretty_printer)
+ {
+ gdbpy_print_stack ();
+ Py_DECREF (constructor);
+ constructor = Py_None;
+ Py_INCREF (constructor);
+ }
+
+ if (pretty_printer == Py_None)
+ {
+ Py_DECREF (pretty_printer);
+ pretty_printer = NULL;
+ }
+ }
+
+ install_visualizer (var, constructor, pretty_printer);
+}
+
+#endif /* HAVE_PYTHON */
+
+/* A helper function for install_new_value. This creates and installs
+ a visualizer for VAR, if appropriate. */
+
+static void
+install_new_value_visualizer (struct varobj *var)
+{
+#if HAVE_PYTHON
+ /* If the constructor is None, then we want the raw value. If VAR
+ does not have a value, just skip this. */
+ if (var->constructor != Py_None && var->value)
+ {
+ struct cleanup *cleanup;
+ PyObject *pretty_printer = NULL;
+
+ cleanup = varobj_ensure_python_env (var);
+
+ if (!var->constructor)
+ install_default_visualizer (var);
+ else
+ construct_visualizer (var, var->constructor);
+
+ do_cleanups (cleanup);
+ }
+#else
+ /* Do nothing. */
+#endif
+}
+
/* Assign a new value to a variable object. If INITIAL is non-zero,
this is the first assignement after the variable object was just
created, or changed type. In that case, just assign the value
@@ -1206,10 +1459,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
that in C++ a reference is not rebindable, it cannot
meaningfully change. So, get hold of the real value. */
if (value)
- {
- value = coerce_ref (value);
- release_value (value);
- }
+ value = coerce_ref (value);
if (var->type && TYPE_CODE (var->type) == TYPE_CODE_UNION)
/* For unions, we need to fetch the value implicitly because
@@ -1256,7 +1506,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
values. Don't get string rendering if the value is
lazy -- if it is, the code above has decided that the value
should not be fetched. */
- if (value && !value_lazy (value))
+ if (value && !value_lazy (value) && !var->pretty_printer)
print_value = value_get_print_value (value, var->format, var);
/* If the type is changeable, compare the old and the new values.
@@ -1272,7 +1522,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
{
changed = 1;
}
- else
+ else if (! var->pretty_printer)
{
/* Try to compare the values. That requires that both
values are non-lazy. */
@@ -1317,74 +1567,53 @@ install_new_value (struct varobj *var, struct value *value, int initial)
if (var->value != NULL && var->value != value)
value_free (var->value);
var->value = value;
- if (var->print_value)
- xfree (var->print_value);
- var->print_value = print_value;
+ if (value != NULL)
+ value_incref (value);
if (value && value_lazy (value) && intentionally_not_fetched)
var->not_fetched = 1;
else
var->not_fetched = 0;
var->updated = 0;
+ install_new_value_visualizer (var);
+
+ /* If we installed a pretty-printer, re-compare the printed version
+ to see if the variable changed. */
+ if (var->pretty_printer)
+ {
+ xfree (print_value);
+ print_value = value_get_print_value (var->value, var->format, var);
+ if (!var->print_value || strcmp (var->print_value, print_value) != 0)
+ changed = 1;
+ }
+ if (var->print_value)
+ xfree (var->print_value);
+ var->print_value = print_value;
+
gdb_assert (!var->value || value_type (var->value));
return changed;
}
-static void
-install_visualizer (struct varobj *var, PyObject *visualizer)
+/* Return the requested range for a varobj. VAR is the varobj. FROM
+ and TO are out parameters; *FROM and *TO will be set to the
+ selected sub-range of VAR. If no range was selected using
+ -var-set-update-range, then both will be -1. */
+void
+varobj_get_child_range (struct varobj *var, int *from, int *to)
{
-#if HAVE_PYTHON
- /* If there are any children now, wipe them. */
- varobj_delete (var, NULL, 1 /* children only */);
- var->num_children = -1;
-
- Py_XDECREF (var->pretty_printer);
- var->pretty_printer = visualizer;
-
- install_new_value (var, var->value, 1);
-
- /* If we removed the visualizer, and the user ever requested the
- object's children, then we must compute the list of children.
- Note that we needn't do this when installing a visualizer,
- because updating will recompute dynamic children. */
- if (!visualizer && var->children_requested)
- varobj_list_children (var);
-#else
- error (_("Python support required"));
-#endif
+ *from = var->from;
+ *to = var->to;
}
-static void
-install_default_visualizer (struct varobj *var)
+/* Set the selected sub-range of children of VAR to start at index
+ FROM and end at index TO. If either FROM or TO is less than zero,
+ this is interpreted as a request for all children. */
+void
+varobj_set_child_range (struct varobj *var, int from, int to)
{
-#if HAVE_PYTHON
- struct cleanup *cleanup;
- PyObject *pretty_printer = NULL;
-
- cleanup = varobj_ensure_python_env (var);
-
- if (var->value)
- {
- pretty_printer = gdbpy_get_varobj_pretty_printer (var->value);
- if (! pretty_printer)
- {
- gdbpy_print_stack ();
- error (_("Cannot instantiate printer for default visualizer"));
- }
- }
-
- if (pretty_printer == Py_None)
- {
- Py_DECREF (pretty_printer);
- pretty_printer = NULL;
- }
-
- install_visualizer (var, pretty_printer);
- do_cleanups (cleanup);
-#else
- /* No error is right as this function is inserted just as a hook. */
-#endif
+ var->from = from;
+ var->to = to;
}
void
@@ -1402,31 +1631,19 @@ varobj_set_visualizer (struct varobj *var, const char *visualizer)
make_cleanup_py_decref (globals);
constructor = PyRun_String (visualizer, Py_eval_input, globals, globals);
-
- /* Do not instantiate NoneType. */
- if (constructor == Py_None)
- {
- pretty_printer = Py_None;
- Py_INCREF (pretty_printer);
- }
- else
- pretty_printer = instantiate_pretty_printer (constructor, var->value);
-
- Py_XDECREF (constructor);
- if (! pretty_printer)
+ if (! constructor)
{
gdbpy_print_stack ();
error (_("Could not evaluate visualizer expression: %s"), visualizer);
}
- if (pretty_printer == Py_None)
- {
- Py_DECREF (pretty_printer);
- pretty_printer = NULL;
- }
+ construct_visualizer (var, constructor);
+ Py_XDECREF (constructor);
- install_visualizer (var, pretty_printer);
+ /* If there are any children now, wipe them. */
+ varobj_delete (var, NULL, 1 /* children only */);
+ var->num_children = -1;
do_cleanups (back_to);
#else
@@ -1537,44 +1754,75 @@ VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit)
/* We probably should not get children of a varobj that has a
pretty-printer, but for which -var-list-children was never
- invoked. Presumably, such varobj is not yet expanded in the
- UI, so we need not bother getting it. */
+ invoked. */
if (v->pretty_printer)
{
- VEC (varobj_p) *changed = 0, *new_and_unchanged = 0;
+ VEC (varobj_p) *changed = 0, *new = 0, *unchanged = 0;
int i, children_changed;
varobj_p tmp;
- if (!v->children_requested)
- continue;
-
if (v->frozen)
continue;
+ if (!v->children_requested)
+ {
+ int dummy;
+
+ /* If we initially did not have potential children, but
+ now we do, consider the varobj as changed.
+ Otherwise, if children were never requested, consider
+ it as unchanged -- presumably, such varobj is not yet
+ expanded in the UI, so we need not bother getting
+ it. */
+ if (!varobj_has_more (v, 0))
+ {
+ update_dynamic_varobj_children (v, NULL, NULL, NULL,
+ &dummy, 0, 0, 0);
+ if (varobj_has_more (v, 0))
+ r.changed = 1;
+ }
+
+ if (r.changed)
+ VEC_safe_push (varobj_update_result, result, &r);
+
+ continue;
+ }
+
/* If update_dynamic_varobj_children returns 0, then we have
a non-conforming pretty-printer, so we skip it. */
- if (update_dynamic_varobj_children (v, &changed, &new_and_unchanged,
- &children_changed))
+ if (update_dynamic_varobj_children (v, &changed, &new, &unchanged,
+ &children_changed, 1,
+ v->from, v->to))
{
- if (children_changed)
- r.children_changed = 1;
- for (i = 0; VEC_iterate (varobj_p, changed, i, tmp); ++i)
+ if (children_changed || new)
{
- varobj_update_result r = {tmp};
- r.changed = 1;
- r.value_installed = 1;
- VEC_safe_push (varobj_update_result, stack, &r);
+ r.children_changed = 1;
+ r.new = new;
}
- for (i = 0;
- VEC_iterate (varobj_p, new_and_unchanged, i, tmp);
- ++i)
+ for (i = 0; VEC_iterate (varobj_p, changed, i, tmp); ++i)
{
varobj_update_result r = {tmp};
+ r.changed = 1;
r.value_installed = 1;
VEC_safe_push (varobj_update_result, stack, &r);
}
+ for (i = 0; VEC_iterate (varobj_p, unchanged, i, tmp); ++i)
+ {
+ if (!tmp->frozen)
+ {
+ varobj_update_result r = {tmp};
+ r.value_installed = 1;
+ VEC_safe_push (varobj_update_result, stack, &r);
+ }
+ }
if (r.changed || r.children_changed)
VEC_safe_push (varobj_update_result, result, &r);
+
+ /* Free CHANGED and UNCHANGED, but not NEW, because NEW
+ has been put into the result vector. */
+ VEC_free (varobj_p, changed);
+ VEC_free (varobj_p, unchanged);
+
continue;
}
}
@@ -1862,7 +2110,12 @@ new_variable (void)
var->frozen = 0;
var->not_fetched = 0;
var->children_requested = 0;
+ var->from = -1;
+ var->to = -1;
+ var->constructor = 0;
var->pretty_printer = 0;
+ var->child_iter = 0;
+ var->saved_item = 0;
return var;
}
@@ -1892,7 +2145,10 @@ free_variable (struct varobj *var)
if (var->pretty_printer)
{
struct cleanup *cleanup = varobj_ensure_python_env (var);
- Py_DECREF (var->pretty_printer);
+ Py_XDECREF (var->constructor);
+ Py_XDECREF (var->pretty_printer);
+ Py_XDECREF (var->child_iter);
+ Py_XDECREF (var->saved_item);
do_cleanups (cleanup);
}
#endif
@@ -2139,6 +2395,8 @@ value_of_root (struct varobj **var_handle, int *type_changed)
else
{
tmp_var->obj_name = xstrdup (var->obj_name);
+ tmp_var->from = var->from;
+ tmp_var->to = var->to;
varobj_delete (var, NULL, 0);
install_variable (tmp_var);
@@ -2173,7 +2431,11 @@ static char *
my_value_of_variable (struct varobj *var, enum varobj_display_formats format)
{
if (var->root->is_valid)
- return (*var->root->lang->value_of_variable) (var, format);
+ {
+ if (var->pretty_printer)
+ return value_get_print_value (var->value, var->format, var);
+ return (*var->root->lang->value_of_variable) (var, format);
+ }
else
return NULL;
}
@@ -2196,43 +2458,51 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
struct cleanup *back_to = varobj_ensure_python_env (var);
PyObject *value_formatter = var->pretty_printer;
- if (value_formatter && PyObject_HasAttr (value_formatter,
- gdbpy_to_string_cst))
+ if (value_formatter)
{
- char *hint;
- struct value *replacement;
- int string_print = 0;
- PyObject *output = NULL;
+ /* First check to see if we have any children at all. If so,
+ we simply return {...}. */
+ if (dynamic_varobj_has_child_method (var))
+ return xstrdup ("{...}");
- hint = gdbpy_get_display_hint (value_formatter);
- if (hint)
+ if (PyObject_HasAttr (value_formatter, gdbpy_to_string_cst))
{
- if (!strcmp (hint, "string"))
- string_print = 1;
- xfree (hint);
- }
+ char *hint;
+ struct value *replacement;
+ int string_print = 0;
+ PyObject *output = NULL;
+
+ hint = gdbpy_get_display_hint (value_formatter);
+ if (hint)
+ {
+ if (!strcmp (hint, "string"))
+ string_print = 1;
+ xfree (hint);
+ }
- output = apply_varobj_pretty_printer (value_formatter,
- &replacement);
- if (output)
- {
- PyObject *py_str = python_string_to_target_python_string (output);
- if (py_str)
- {
- char *s = PyString_AsString (py_str);
- len = PyString_Size (py_str);
- thevalue = xmemdup (s, len + 1, len + 1);
- Py_DECREF (py_str);
+ output = apply_varobj_pretty_printer (value_formatter,
+ &replacement);
+ if (output)
+ {
+ PyObject *py_str
+ = python_string_to_target_python_string (output);
+ if (py_str)
+ {
+ char *s = PyString_AsString (py_str);
+ len = PyString_Size (py_str);
+ thevalue = xmemdup (s, len + 1, len + 1);
+ Py_DECREF (py_str);
+ }
+ Py_DECREF (output);
}
- Py_DECREF (output);
- }
- if (thevalue && !string_print)
- {
- do_cleanups (back_to);
- return thevalue;
+ if (thevalue && !string_print)
+ {
+ do_cleanups (back_to);
+ return thevalue;
+ }
+ if (replacement)
+ value = replacement;
}
- if (replacement)
- value = replacement;
}
do_cleanups (back_to);
}
@@ -2961,10 +3231,7 @@ cplus_describe_child (struct varobj *parent, int index,
*cname = xstrdup (TYPE_FIELD_NAME (type, index));
if (cvalue && value)
- {
- *cvalue = value_cast (TYPE_FIELD_TYPE (type, index), value);
- release_value (*cvalue);
- }
+ *cvalue = value_cast (TYPE_FIELD_TYPE (type, index), value);
if (ctype)
{
diff --git a/gdb/varobj.h b/gdb/varobj.h
index 7297243..f43c593 100644
--- a/gdb/varobj.h
+++ b/gdb/varobj.h
@@ -78,6 +78,12 @@ typedef struct varobj_update_result_t
new value of varobj is already computed and installed, or has to
be yet installed. Don't use this outside varobj.c */
int value_installed;
+
+ /* This will be non-NULL when new children were added to the varobj.
+ It lists the new children (which must necessarily come at the end
+ of the child list) added during an update. The caller is
+ responsible for freeing this vector. */
+ VEC (varobj_p) *new;
} varobj_update_result;
DEF_VEC_O (varobj_update_result);
@@ -112,13 +118,24 @@ extern void varobj_set_frozen (struct varobj *var, int frozen);
extern int varobj_get_frozen (struct varobj *var);
+extern void varobj_get_child_range (struct varobj *var, int *from, int *to);
+
+extern void varobj_set_child_range (struct varobj *var, int from, int to);
+
extern char *varobj_get_display_hint (struct varobj *var);
extern int varobj_get_num_children (struct varobj *var);
-/* Return the list of children of VAR. The returned vector
- should not be modified in any way. */
-extern VEC (varobj_p)* varobj_list_children (struct varobj *var);
+/* Return the list of children of VAR. The returned vector should not
+ be modified in any way. FROM and TO are in/out parameters
+ indicating the range of children to return. If either *FROM or *TO
+ is less than zero on entry, then all children will be returned. On
+ return, *FROM and *TO will be updated to indicate the real range
+ that was returned. The resulting VEC will contain at least the
+ children from *FROM to just before *TO; it might contain more
+ children, depending on whether any more were available. */
+extern VEC (varobj_p)* varobj_list_children (struct varobj *var,
+ int *from, int *to);
extern char *varobj_get_type (struct varobj *var);
@@ -149,6 +166,13 @@ extern int varobj_editable_p (struct varobj *var);
extern int varobj_floating_p (struct varobj *var);
-extern void varobj_set_visualizer (struct varobj *var, const char *visualizer);
+extern void
+varobj_set_visualizer (struct varobj *var, const char *visualizer);
+
+extern void varobj_enable_pretty_printing (void);
+
+extern int varobj_has_more (struct varobj *var, int to);
+
+extern int varobj_pretty_printed_p (struct varobj *var);
#endif /* VAROBJ_H */
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-14 19:59 ` Tom Tromey
@ 2009-09-14 22:55 ` Nick Roberts
2009-09-15 15:37 ` Tom Tromey
2009-09-16 5:44 ` Vladimir Prus
1 sibling, 1 reply; 39+ messages in thread
From: Nick Roberts @ 2009-09-14 22:55 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
> I think we've been conservative enough about this code that it is
> probably reasonable to let people rely on it. It has been through a lot
> of vetting.
>
> However, I don't mind adding a note to the manual if other maintainers
> want that.
Some of the the headaches of MI are due to legacy code. Hence mi0, mi1, mi2,
etc. I don't know if others are already using these features but it would
seem sensible to me for frontends to _drive_ MI and not for it to be the other
way around. For example, here are a couple changes that I would like to see:
1) The displayhint field output from -var-create as well/or instead of from
-var-list-children. That would be useful for determining whether an element
should be expandable or not. Types map, list -- yes, type string -- no.
With normal variable objects I just use num_children but this isn't sufficient
for dynamic ones.
2) If is_map is true, rather than:
var1.0 = key0
var1.1 = value0
var1.2 = key1
var1.0 = vaue1
...
I would prefer GDB to output:
var1.0 = "map_element"
var1.0.key = key0
var1.0.value = value0
var1.1 = "map_element"
var1.1.key = key1
var1.1.value = value1
That way the values could be displayed as a tree:
[-]--0
| |
| |--key0
| |
| |--value0
|
[-]--1
| |
| |--key1
| |
| |--value1
--
Nick http://www.inet.net.nz/~nickrob
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-14 20:05 ` Tom Tromey
2009-09-14 20:24 ` Eli Zaretskii
@ 2009-09-14 23:58 ` Nick Roberts
1 sibling, 0 replies; 39+ messages in thread
From: Nick Roberts @ 2009-09-14 23:58 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
> Also, I fixed the bug that Nick reported whereby the "from" parameter of
> -var-set-update-range did not seem to have any effect. I added a
> regression test for this.
This bit looks good now.
--
Nick http://www.inet.net.nz/~nickrob
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-14 21:29 ` Tom Tromey
@ 2009-09-15 3:06 ` Eli Zaretskii
0 siblings, 0 replies; 39+ messages in thread
From: Eli Zaretskii @ 2009-09-15 3:06 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
> From: Tom Tromey <tromey@redhat.com>
> Cc: gdb-patches@sourceware.org
> Date: Mon, 14 Sep 2009 15:29:17 -0600
>
> Here's a new version with all your comments addressed.
Thanks. This is fine.
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-14 22:55 ` Nick Roberts
@ 2009-09-15 15:37 ` Tom Tromey
2009-09-15 22:28 ` Nick Roberts
2009-09-15 22:43 ` Nick Roberts
0 siblings, 2 replies; 39+ messages in thread
From: Tom Tromey @ 2009-09-15 15:37 UTC (permalink / raw)
To: Nick Roberts; +Cc: gdb-patches
>>>>> "Nick" == Nick Roberts <nickrob@snap.net.nz> writes:
Nick> I don't know if others are already using these features but it
Nick> would seem sensible to me for frontends to _drive_ MI and not for
Nick> it to be the other way around.
Yeah; the first very round of code was really done in isolation but
since then, Vladimir has been trying things out in his GUI, and we've
had another user doing the same.
Nick> 1) The displayhint field output from -var-create as well/or
Nick> instead of from -var-list-children. That would be useful for
Nick> determining whether an element should be expandable or not. Types
Nick> map, list -- yes, type string -- no. With normal variable objects
Nick> I just use num_children but this isn't sufficient for dynamic
Nick> ones.
I can add displayhint to the -var-create output quite easily. It seems
like a good idea; I will implement it soon.
With a dynamic varobj you can tell if it has children by examining the
has_more attribute.
Nick> 2) If is_map is true, rather than:
[...]
Nick> I would prefer GDB to output:
Nick> var1.0 = "map_element"
Nick> var1.0.key = key0
Nick> var1.0.value = value0
Nick> That way the values could be displayed as a tree:
I considered this back at the start. The problem with doing this is
that the key need not be a scalar. It could be a struct or some other
complicated varobj with children.
Also, the current approach has a benefit because it is simple and
uniform: we can add more display hints without modifying the C code.
Tom
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-15 15:37 ` Tom Tromey
@ 2009-09-15 22:28 ` Nick Roberts
2009-09-16 5:45 ` Vladimir Prus
2009-09-16 17:12 ` Tom Tromey
2009-09-15 22:43 ` Nick Roberts
1 sibling, 2 replies; 39+ messages in thread
From: Nick Roberts @ 2009-09-15 22:28 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
> With a dynamic varobj you can tell if it has children by examining the
> has_more attribute.
The field has_more tells you if it _currently_ has children. If you create a
variable object of a STL container immediately after declaring an empty
container, e.g. after
map<string, int> m;
then has_more=0 yet the node for it would need to be expandable. In Emacs
this means there is a plus sign on the icon in the toolbar. Clicking on
it gives no immediate children but then as you proceed:
l.push_back (1);
l.push_back (2);
the additional children appear. With a string there are never any children
so you would not want an expandable node. AFAICS the only way the front end
can discriminate is through the displayhint field.
On that note, printers.py in libstdc++ doesn't have a displayhint function for
StdListPrinter.
Also there appears to be something wrong with the python class
StdVectorPrinter because if you create a variable object immediately after
declaring it, e.g. after
vector<int> v(4); // create vector of integers with 4 elts
then do -var-list-children, GDB hangs:
-var-create - * v
^done,name="var1",numchild="0",value="{...}",type="std::vector<int, std::allocator<int> >",thread-id="1",dynamic="1",has_more="1"
(gdb)
-var-list-children var1
p v gives:
p v
&"p v\n"
~"$1 = std::vector of length -17178288109, capacity 35167192218076 = {"
&"Cannot access memory at address 0x1000000006\n"
^error,msg="Cannot access memory at address 0x1000000006"
(gdb)
while a similar declaration for list just prints with uninitialised values.
--
Nick http://www.inet.net.nz/~nickrob
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-15 15:37 ` Tom Tromey
2009-09-15 22:28 ` Nick Roberts
@ 2009-09-15 22:43 ` Nick Roberts
2009-09-16 5:39 ` Vladimir Prus
1 sibling, 1 reply; 39+ messages in thread
From: Nick Roberts @ 2009-09-15 22:43 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
> Nick> 2) If is_map is true, rather than:
> [...]
> Nick> I would prefer GDB to output:
> Nick> var1.0 = "map_element"
> Nick> var1.0.key = key0
> Nick> var1.0.value = value0
>
> Nick> That way the values could be displayed as a tree:
>
> I considered this back at the start. The problem with doing this is
> that the key need not be a scalar. It could be a struct or some other
> complicated varobj with children.
It's probably unusual for the key to be a structure but that wouldn't be a
problem and it in could be expanded in turn. Something like (I'm not a C++
programmer and maybe values would need some kind of comparator to be defined):
struct values
{
int a;
float b;
};
map<values*, string> m1;
struct values val = {a : 5, b : 7.5};
struct values *v;
*v = val;
m1[v] = "a string";
-var-create - * m1
-var-list-children -var1
var1.0 = "map_element"
var1.0.key = key0
var1.0.key.a = 5
var1.0.key.b = 7.5
var1.0.value = "a string"
> Also, the current approach has a benefit because it is simple and
> uniform: we can add more display hints without modifying the C code.
and
> Nick> For collections, it would seem useful to have some kind of index number.
> That would be fine by me.
var1.0 above would provide the index.
--
Nick http://www.inet.net.nz/~nickrob
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-15 22:43 ` Nick Roberts
@ 2009-09-16 5:39 ` Vladimir Prus
2009-09-16 9:36 ` Nick Roberts
0 siblings, 1 reply; 39+ messages in thread
From: Vladimir Prus @ 2009-09-16 5:39 UTC (permalink / raw)
To: gdb-patches
Nick Roberts wrote:
> > Nick> 2) If is_map is true, rather than:
> > [...]
> > Nick> I would prefer GDB to output:
> > Nick> var1.0 = "map_element"
> > Nick> var1.0.key = key0
> > Nick> var1.0.value = value0
> >
> > Nick> That way the values could be displayed as a tree:
> >
> > I considered this back at the start. The problem with doing this is
> > that the key need not be a scalar. It could be a struct or some other
> > complicated varobj with children.
>
> It's probably unusual for the key to be a structure
Rather, it's very typical in C++. std::map<std::string, whatever> is used
all over.
> but that wouldn't be a
> problem and it in could be expanded in turn. Something like (I'm not a C++
> programmer and maybe values would need some kind of comparator to be defined):
>
> struct values
> {
> int a;
> float b;
> };
>
> map<values*, string> m1;
>
> struct values val = {a : 5, b : 7.5};
> struct values *v;
> *v = val;
>
> m1[v] = "a string";
>
>
> -var-create - * m1
> -var-list-children -var1
>
> var1.0 = "map_element"
> var1.0.key = key0
> var1.0.key.a = 5
> var1.0.key.b = 7.5
> var1.0.value = "a string"
What if 'values' wishes to have a field named 'key'?
- Volodya
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-14 19:59 ` Tom Tromey
2009-09-14 22:55 ` Nick Roberts
@ 2009-09-16 5:44 ` Vladimir Prus
2009-09-16 23:52 ` RFA: mark -enable-pretty-printing as experimental (Was: Patch: implement new dynamic varobj spec) Tom Tromey
1 sibling, 1 reply; 39+ messages in thread
From: Vladimir Prus @ 2009-09-16 5:44 UTC (permalink / raw)
To: gdb-patches
Tom Tromey wrote:
>>>>>> "Nick" == Nick Roberts <nickrob@snap.net.nz> writes:
>
> Nick> I would really like to use these improvements in Emacs but the
> Nick> release isn't far away. So I would request that
> Nick> -enable-pretty-printing is marked as an EXPERIMENTAL feature in
> Nick> the manual. That way changes can be made without anyone
> Nick> complaining. Maybe by 7.1 early next year there will be frontends
> Nick> that have worked out how to use it and that marking could be
> Nick> removed.
>
> I think we've been conservative enough about this code that it is
> probably reasonable to let people rely on it. It has been through a lot
> of vetting.
>
> However, I don't mind adding a note to the manual if other maintainers
> want that.
I think it makes sense. You list 3 known issues in the original email,
and while I hope we'll fix them by 7.0, there will be just too little time
for extensive testing. Let's keep our options open for a bit more.
- Volodya
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-15 22:28 ` Nick Roberts
@ 2009-09-16 5:45 ` Vladimir Prus
2009-09-16 9:56 ` Nick Roberts
2009-09-16 17:12 ` Tom Tromey
1 sibling, 1 reply; 39+ messages in thread
From: Vladimir Prus @ 2009-09-16 5:45 UTC (permalink / raw)
To: gdb-patches
Nick Roberts wrote:
> > With a dynamic varobj you can tell if it has children by examining the
> > has_more attribute.
>
> The field has_more tells you if it _currently_ has children. If you create a
> variable object of a STL container immediately after declaring an empty
> container, e.g. after
>
> map<string, int> m;
>
> then has_more=0 yet the node for it would need to be expandable. In Emacs
> this means there is a plus sign on the icon in the toolbar. Clicking on
> it gives no immediate children but then as you proceed:
>
> l.push_back (1);
> l.push_back (2);
>
> the additional children appear. With a string there are never any children
> so you would not want an expandable node. AFAICS the only way the front end
> can discriminate is through the displayhint field.
Right, so for string you'll have numchildren=0, has_more=0, and no need to
make anything expandable. For vector that is initially empty, you'll have
the same, so it won't be expandable, but if things are pushed, -var-update
will report has_more=1. You can detect that, and make the item expandable
at this point.
- Volodya
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-16 23:53 ` Tom Tromey
@ 2009-09-16 5:46 ` Vladimir Prus
2009-09-19 12:01 ` Matt Rice
1 sibling, 0 replies; 39+ messages in thread
From: Vladimir Prus @ 2009-09-16 5:46 UTC (permalink / raw)
To: tromey; +Cc: gdb-patches
On Tuesday 15 September 2009 Tom Tromey wrote:
> >>>>> "Volodya" == Vladimir Prus <vladimir@codesourcery.com> writes:
>
> Volodya> For avoidance of doubt, I think this patch should go in. I plan
> Volodya> to read the doc changes, and glance at the code, but I am
> Volodya> fairly confident that this is overall good.
>
> Thanks.
>
> I am checking in the appended. This has a minor difference from
> yesterday's patch: I added displayhint output to -var-create, per Nick's
> suggestion.
Tom,
this is great. Thank you for your work on this, this is a remarkable achievement
that surely will make a lot of users happy.
I'll toggle the last bit to enable this in trunk version of KDevelop, and ask
folks to test.
- Volodya
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-16 5:39 ` Vladimir Prus
@ 2009-09-16 9:36 ` Nick Roberts
0 siblings, 0 replies; 39+ messages in thread
From: Nick Roberts @ 2009-09-16 9:36 UTC (permalink / raw)
To: Vladimir Prus; +Cc: gdb-patches
> > It's probably unusual for the key to be a structure
>
> Rather, it's very typical in C++. std::map<std::string, whatever> is used
> all over.
A string is represented by a single value like a scalar. The case being
considered was "a struct or some other complicated varobj with children".
>...
> > -var-create - * m1
> > -var-list-children -var1
> >
> > var1.0 = "map_element"
> > var1.0.key = key0
> > var1.0.key.a = 5
> > var1.0.key.b = 7.5
> > var1.0.value = "a string"
>
> What if 'values' wishes to have a field named 'key'?
I don't understand. The frontend would know from var1.0 that key value pairs
follow. So presumably:
var1.0.key.key = 5
--
Nick http://www.inet.net.nz/~nickrob
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-16 5:45 ` Vladimir Prus
@ 2009-09-16 9:56 ` Nick Roberts
0 siblings, 0 replies; 39+ messages in thread
From: Nick Roberts @ 2009-09-16 9:56 UTC (permalink / raw)
To: Vladimir Prus; +Cc: gdb-patches
> > the additional children appear. With a string there are never any
> > children so you would not want an expandable node. AFAICS the only way
> > the front end can discriminate is through the displayhint field.
>
> Right, so for string you'll have numchildren=0, has_more=0, and no need to
> make anything expandable. For vector that is initially empty, you'll have
> the same, so it won't be expandable, but if things are pushed, -var-update
> will report has_more=1. You can detect that, and make the item expandable
> at this point.
OK. In that case I misunderstood the meaning of the has_more field. I had
assumed it was just non-zero when -var-set-update-range was restricted.
The documentation states that -var-update returns the list of variable objects
whose values have changed. More precisely:
Here, "changed" means that the result of `-var-evaluate-expression' before
and after the `-var-update' is different.
That appears to no longer be true and its definition needs to be generalised
for dynamic variable objects. Actually I wonder if it might be a good idea to
split the node on variable objects and describe normal (static?) variable
objects and dynamic ones separately. It has become very long and that way the
user won't be overwhelmed by too much information at first reading.
--
Nick http://www.inet.net.nz/~nickrob
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-15 22:28 ` Nick Roberts
2009-09-16 5:45 ` Vladimir Prus
@ 2009-09-16 17:12 ` Tom Tromey
2009-09-16 22:26 ` Nick Roberts
1 sibling, 1 reply; 39+ messages in thread
From: Tom Tromey @ 2009-09-16 17:12 UTC (permalink / raw)
To: Nick Roberts; +Cc: gdb-patches
>>>>> "Nick" == Nick Roberts <nickrob@snap.net.nz> writes:
Tom> With a dynamic varobj you can tell if it has children by examining the
Tom> has_more attribute.
Nick> The field has_more tells you if it _currently_ has children. If
Nick> you create a variable object of a STL container immediately after
Nick> declaring an empty container, e.g. after
Ok, yeah, I see what you mean.
Nick> map<string, int> m;
Nick> then has_more=0 yet the node for it would need to be expandable.
I don't think I understand this, though. There would be nothing
underneath the node. So, showing some expansion control would be weird,
wouldn't it?
Nick> AFAICS the only way the front end can discriminate is through the
Nick> displayhint field.
I would like the display hint to remain just a hint. In particular I
think it is important for future backward compatibility that we don't
require all front ends to know about all possible hints -- that is, it
should always be ok for the front end to ignore a hint it doesn't
understand.
So, if we need a way to determine "might possibly have children", then
let's add a new attribute.
Nick> On that note, printers.py in libstdc++ doesn't have a displayhint
Nick> function for StdListPrinter.
I'll look into this. I'm not sure whether this was intentional or not.
Nick> Also there appears to be something wrong with the python class
Nick> StdVectorPrinter because if you create a variable object immediately after
Nick> declaring it, e.g. after
I'll look at this too, thanks.
Tom
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-16 17:12 ` Tom Tromey
@ 2009-09-16 22:26 ` Nick Roberts
0 siblings, 0 replies; 39+ messages in thread
From: Nick Roberts @ 2009-09-16 22:26 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
> Nick> map<string, int> m;
> Nick> then has_more=0 yet the node for it would need to be expandable.
>
> I don't think I understand this, though. There would be nothing
> underneath the node. So, showing some expansion control would be weird,
> wouldn't it?
Clicking on it wouldn't immediately display children but ensure that they
were displayed when created.
> Nick> AFAICS the only way the front end can discriminate is through the
> Nick> displayhint field.
>
> I would like the display hint to remain just a hint. In particular I
> think it is important for future backward compatibility that we don't
> require all front ends to know about all possible hints -- that is, it
> should always be ok for the front end to ignore a hint it doesn't
> understand.
>
> So, if we need a way to determine "might possibly have children", then
> let's add a new attribute.
Now Vladimir has explained how "has_more" works, I'm happy to use that. As
you say, my approach would require the front end to know about all possible
hints.
--
Nick http://www.inet.net.nz/~nickrob
^ permalink raw reply [flat|nested] 39+ messages in thread
* RFA: mark -enable-pretty-printing as experimental (Was: Patch: implement new dynamic varobj spec)
2009-09-16 5:44 ` Vladimir Prus
@ 2009-09-16 23:52 ` Tom Tromey
[not found] ` <h8vk80$fqc$2@ger.gmane.org>
0 siblings, 1 reply; 39+ messages in thread
From: Tom Tromey @ 2009-09-16 23:52 UTC (permalink / raw)
To: Vladimir Prus; +Cc: gdb-patches
>>>>> "Volodya" == Vladimir Prus <vladimir@codesourcery.com> writes:
Volodya> I think it makes sense. You list 3 known issues in the original
Volodya> email, and while I hope we'll fix them by 7.0, there will be
Volodya> just too little time for extensive testing. Let's keep our
Volodya> options open for a bit more.
How about this?
Tom
2009-09-16 Tom Tromey <tromey@redhat.com>
* gdb.texinfo (GDB/MI Variable Objects): -enable-pretty-printing
is experimental.
cvs diff: Diffing .
Index: gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.624
diff -u -c -r1.624 gdb.texinfo
cvs diff: conflicting specifications of output style
Write failed flushing stdout buffer.
write stdout: Broken pipe
*** gdb.texinfo 15 Sep 2009 18:51:25 -0000 1.624
--- gdb.texinfo 16 Sep 2009 19:02:55 -0000
***************
*** 23547,23552 ****
--- 23547,23555 ----
Note that if Python support has not been compiled into @value{GDBN},
this command will still succeed (and do nothing).
+ This feature is currently experimental, and may work differently in
+ future versions of @value{GDBN}.
+
@subheading The @code{-var-create} Command
@findex -var-create
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-14 11:24 ` Vladimir Prus
@ 2009-09-16 23:53 ` Tom Tromey
2009-09-16 5:46 ` Vladimir Prus
2009-09-19 12:01 ` Matt Rice
0 siblings, 2 replies; 39+ messages in thread
From: Tom Tromey @ 2009-09-16 23:53 UTC (permalink / raw)
To: Vladimir Prus; +Cc: gdb-patches
>>>>> "Volodya" == Vladimir Prus <vladimir@codesourcery.com> writes:
Volodya> For avoidance of doubt, I think this patch should go in. I plan
Volodya> to read the doc changes, and glance at the code, but I am
Volodya> fairly confident that this is overall good.
Thanks.
I am checking in the appended. This has a minor difference from
yesterday's patch: I added displayhint output to -var-create, per Nick's
suggestion.
Tom
2009-09-14 Tom Tromey <tromey@redhat.com>
* varobj.h (varobj_update_result_t) <new>: New field.
(varobj_get_child_range, varobj_set_child_range): Declare.
(varobj_list_children): Update.
(varobj_enable_pretty_printing, varobj_has_more)
(varobj_pretty_printed_p): Declare.
* varobj.c (pretty_printing): New global.
(varobj_enable_pretty_printing): New function.
(struct varobj_root) <from, to, constructor, child_iter,
saved_item>: New fields.
(varobj_create): Don't call install_default_visualizer.
(instantiate_pretty_printer): Don't use value_copy.
(varobj_has_more): New function.
(restrict_range): New function.
(install_dynamic_child): Likewise.
(dynamic_varobj_has_child_method): Likewise.
(update_dynamic_varobj_children): Remove 'new_and_unchanged'
argument; add 'new', 'unchanged', 'from', and 'to' arguments.
Rewrite.
(varobj_get_num_children): Call update_dynamic_varobj_children.
(varobj_list_children): Add 'from' and 'to' arguments. Ignore
result of update_dynamic_varobj_children. Don't call
install_default_visualizer. Restrict result range.
(varobj_add_child): Don't call install_default_visualizer.
(varobj_pretty_printed_p): New function.
(install_visualizer): Rewrite. Move earlier in file.
(install_default_visualizer): Likewise.
(construct_visualizer): New function.
(install_new_value_visualizer): Likewise.
(install_new_value): Don't call release_value. Special case
pretty-printed objects. Use value_incref. Rearrange "changed"
logic.
(varobj_get_child_range): New function.
(varobj_set_child_range): Likewise.
(varobj_set_visualizer): Rewrite.
(varobj_update): Rewrite pretty-printing logic.
(new_variable): Initialize new fields.
(free_variable): Destroy new fields.
(value_of_root): Copy 'from' and 'to'.
(my_value_of_variable): Handle pretty-printers.
(value_get_print_value): Rework pretty-printing logic.
(cplus_describe_child): Don't use release_value.
* mi/mi-cmds.h (mi_cmd_enable_pretty_printing)
(mi_cmd_var_set_update_range): Declare.
* mi/mi-cmds.c (mi_cmds): Add enable-pretty-printing and
var-set-update-range.
* mi/mi-cmd-var.c (print_varobj): Update. Emit "dynamic"
attribute.
(mi_cmd_var_create): Emit "has_more" attribute.
(mi_cmd_var_set_format): Plug memory leak.
(mi_print_value_p): Replace 'type' argument with 'var'. Handle
pretty-printed varobjs.
(mi_cmd_var_list_children): Accept 'from' and 'to' arguments.
Emit "has_more" attribute.
(mi_cmd_var_evaluate_expression): Plug memory leak.
(mi_cmd_var_assign): Likewise.
(varobj_update_one): Likewise. Emit "dynamic", "has_more", and
"new_children" attributes.
(mi_cmd_enable_pretty_printing): New function.
(mi_cmd_var_set_update_range): Likewise.
2009-09-14 Tom Tromey <tromey@redhat.com>
* gdb.texinfo (GDB/MI Variable Objects): Document
-enable-pretty-printing, -var-set-update-range, dynamic varobjs.
Expand -var-update documentation.
2009-09-14 Tom Tromey <tromey@redhat.com>
* lib/mi-support.exp (mi_create_varobj): Update.
(mi_create_floating_varobj): Likewise.
(mi_create_dynamic_varobj): New proc.
(mi_varobj_update): Update.
(mi_varobj_update_with_type_change): Likewise.
(mi_varobj_update_kv_helper): New proc.
(mi_varobj_update_dynamic_helper): Rewrite.
(mi_varobj_update_dynamic): New proc.
(mi_list_varobj_children): Update.
(mi_list_varobj_children_range): Add 'from' and 'to' arguments.
* gdb.python/python-prettyprint.py (pp_outer): New class.
(pp_nullstr): Likewise.
(lookup_function): Register new printers.
* gdb.python/python-prettyprint.c (struct substruct): New type.
(struct outerstruct): Likewise.
(substruct_test): New function.
(struct nullstr): New type.
(string_1, string_2): New globals.
(main): Add new tests.
* gdb.python/python-mi.exp: Added regression tests.
* gdb.mi/mi2-var-display.exp: Update.
* gdb.mi/mi2-var-cmd.exp: Update.
* gdb.mi/mi2-var-child.exp: Update.
* gdb.mi/mi2-var-block.exp: Update.
* gdb.mi/mi-var-invalidate.exp: Update.
* gdb.mi/mi-var-display.exp: Update.
* gdb.mi/mi-var-cmd.exp: Update.
* gdb.mi/mi-var-child.exp: Update.
* gdb.mi/mi-var-block.exp: Update.
* gdb.mi/mi-break.exp: Update.
* gdb.mi/gdb701.exp: Update.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 7b26675..a1046c5 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -23360,6 +23360,8 @@ access this functionality:
@item @strong{Operation}
@tab @strong{Description}
+@item @code{-enable-pretty-printing}
+@tab enable Python-based pretty-printing
@item @code{-var-create}
@tab create a variable object
@item @code{-var-delete}
@@ -23388,6 +23390,8 @@ access this functionality:
@tab update the variable and its children
@item @code{-var-set-frozen}
@tab set frozeness attribute
+@item @code{-var-set-update-range}
+@tab set range of children to display on update
@end multitable
In the next subsection we describe each operation in detail and suggest
@@ -23395,6 +23399,23 @@ how it can be used.
@subheading Description And Use of Operations on Variable Objects
+@subheading The @code{-enable-pretty-printing} Command
+@findex -enable-pretty-printing
+
+@smallexample
+-enable-pretty-printing
+@end smallexample
+
+@value{GDBN} allows Python-based visualizers to affect the output of the
+MI variable object commands. However, because there was no way to
+implement this in a fully backward-compatible way, a front end must
+request that this functionality be enabled.
+
+Once enabled, this feature cannot be disabled.
+
+Note that if Python support has not been compiled into @value{GDBN},
+this command will still succeed (and do nothing).
+
@subheading The @code{-var-create} Command
@findex -var-create
@@ -23434,15 +23455,61 @@ begin with a @samp{*}), or one of the following:
@samp{$@var{regname}} --- a CPU register name
@end itemize
+@cindex dynamic varobj
+A varobj's contents may be provided by a Python-based pretty-printer. In this
+case the varobj is known as a @dfn{dynamic varobj}. Dynamic varobjs
+have slightly different semantics in some cases. If the
+@code{-enable-pretty-printing} command is not sent, then @value{GDBN}
+will never create a dynamic varobj. This ensures backward
+compatibility for existing clients.
+
@subsubheading Result
-This operation returns the name, number of children and the type of the
-object created. Type is returned as a string as the ones generated by
-the @value{GDBN} CLI. If a fixed variable object is bound to a
-specific thread, the thread is is also printed:
+This operation returns attributes of the newly-created varobj. These
+are:
+
+@table @samp
+@item name
+The name of the varobj.
+
+@item numchild
+The number of children of the varobj. This number is not necessarily
+reliable for a dynamic varobj. Instead, you must examine the
+@samp{has_more} attribute.
+
+@item value
+The varobj's scalar value. For a varobj whose type is some sort of
+aggregate (e.g., a @code{struct}), or for a dynamic varobj, this value
+will not be interesting.
+
+@item type
+The varobj's type. This is a string representation of the type, as
+would be printed by the @value{GDBN} CLI.
+
+@item thread-id
+If a variable object is bound to a specific thread, then this is the
+thread's identifier.
+
+@item has_more
+For a dynamic varobj, this indicates whether there appear to be any
+children available. For a non-dynamic varobj, this will be 0.
+
+@item dynamic
+This attribute will be present and have the value @samp{1} if the
+varobj is a dynamic varobj. If the varobj is not a dynamic varobj,
+then this attribute will not be present.
+
+@item displayhint
+A dynamic varobj can supply a display hint to the front end. The
+value comes directly from the Python pretty-printer object's
+@code{display_hint} method. @xref{Pretty Printing}.
+@end table
+
+Typical output will look like this:
@smallexample
- name="@var{name}",numchild="@var{N}",type="@var{type}",thread-id="@var{M}"
+ name="@var{name}",numchild="@var{N}",type="@var{type}",thread-id="@var{M}",
+ has_more="@var{has_more}"
@end smallexample
@@ -23520,6 +23587,10 @@ Returns the number of children of a variable object @var{name}:
numchild=@var{n}
@end smallexample
+Note that this number is not completely reliable for a dynamic varobj.
+It will return the current number of children, but more children may
+be available.
+
@subheading The @code{-var-list-children} Command
@findex -var-list-children
@@ -23527,7 +23598,7 @@ Returns the number of children of a variable object @var{name}:
@subsubheading Synopsis
@smallexample
- -var-list-children [@var{print-values}] @var{name}
+ -var-list-children [@var{print-values}] @var{name} [@var{from} @var{to}]
@end smallexample
@anchor{-var-list-children}
@@ -23540,6 +23611,22 @@ values; and if it is 2 or @code{--simple-values} print the name and
value for simple data types and just the name for arrays, structures
and unions.
+@var{from} and @var{to}, if specified, indicate the range of children
+to report. If @var{from} or @var{to} is less than zero, the range is
+reset and all children will be reported. Otherwise, children starting
+at @var{from} (zero-based) and up to and excluding @var{to} will be
+reported.
+
+If a child range is requested, it will only affect the current call to
+@code{-var-list-children}, but not future calls to @code{-var-update}.
+For this, you must instead use @code{-var-set-update-range}. The
+intent of this approach is to enable a front end to implement any
+update approach it likes; for example, scrolling a view may cause the
+front end to request more children with @code{-var-list-children}, and
+then the front end could call @code{-var-set-update-range} with a
+different range to ensure that future updates are restricted to just
+the visible items.
+
For each child the following results are returned:
@table @var
@@ -23551,13 +23638,21 @@ Name of the variable object created for this child.
The expression to be shown to the user by the front end to designate this child.
For example this may be the name of a structure member.
+For a dynamic varobj, this value cannot be used to form an
+expression. There is no way to do this at all with a dynamic varobj.
+
For C/C@t{++} structures there are several pseudo children returned to
designate access qualifiers. For these pseudo children @var{exp} is
@samp{public}, @samp{private}, or @samp{protected}. In this case the
type and value are not present.
+A dynamic varobj will not report the access qualifying
+pseudo-children, regardless of the language. This information is not
+available at all with a dynamic varobj.
+
@item numchild
-Number of children this child has.
+Number of children this child has. For a dynamic varobj, this will be
+0.
@item type
The type of the child.
@@ -23573,6 +23668,19 @@ Otherwise this result is not present.
If the variable object is frozen, this variable will be present with a value of 1.
@end table
+The result may have its own attributes:
+
+@table @samp
+@item displayhint
+A dynamic varobj can supply a display hint to the front end. The
+value comes directly from the Python pretty-printer object's
+@code{display_hint} method. @xref{Pretty Printing}.
+
+@item has_more
+This is an integer attribute which is nonzero if there are children
+remaining after the end of the selected range.
+@end table
+
@subsubheading Example
@smallexample
@@ -23649,6 +23757,9 @@ result can be used only for UI presentation. Typical use of
the @code{-var-info-path-expression} command is creating a
watchpoint from a variable object.
+This command is currently not valid for children of a dynamic varobj,
+and will give an error when invoked on one.
+
For example, suppose @code{C} is a C@t{++} class, derived from class
@code{Base}, and that the @code{Base} class has a member called
@code{m_size}. Assume a variable @code{c} is has the type of
@@ -23754,21 +23865,25 @@ With the @samp{*} parameter, if a variable object is bound to a
currently running thread, it will not be updated, without any
diagnostic.
-@subsubheading Example
+If @code{-var-set-update-range} was previously used on a varobj, then
+only the selected range of children will be reported.
-@smallexample
-(gdb)
--var-assign var1 3
-^done,value="3"
-(gdb)
--var-update --all-values var1
-^done,changelist=[@{name="var1",value="3",in_scope="true",
-type_changed="false"@}]
-(gdb)
-@end smallexample
+@code{-var-update} reports all the changed varobjs in a tuple named
+@samp{changelist}.
+
+Each item in the change list is itself a tuple holding:
+
+@table @samp
+@item name
+The name of the varobj.
+
+@item value
+If values were requested for this update, then this field will be
+present and will hold the value of the varobj.
+@item in_scope
@anchor{-var-update}
-The field in_scope may take three values:
+This field is a string which may take one of three values:
@table @code
@item "true"
@@ -23790,6 +23905,61 @@ objects.
In the future new values may be added to this list so the front should
be prepared for this possibility. @xref{GDB/MI Development and Front Ends, ,@sc{GDB/MI} Development and Front Ends}.
+@item type_changed
+This is only present if the varobj is still valid. If the type
+changed, then this will be the string @samp{true}; otherwise it will
+be @samp{false}.
+
+@item new_type
+If the varobj's type changed, then this field will be present and will
+hold the new type.
+
+@item new_num_children
+For a dynamic varobj, if the number of children changed, or if the
+type changed, this will be the new number of children.
+
+The @samp{numchild} field in other varobj responses is generally not
+valid for a dynamic varobj -- it will show the number of children that
+@value{GDBN} knows about, but because dynamic varobjs lazily
+instantiate their children, this will not reflect the number of
+children which may be available.
+
+The @samp{new_num_children} attribute only reports changes to the
+number of children known by @value{GDBN}. This is the only way to
+detect whether an update has removed children (which necessarily can
+only happen at the end of the update range).
+
+@item displayhint
+The display hint, if any.
+
+@item has_more
+This is an integer value, which will be 1 if there are more children
+available outside the varobj's update range.
+
+@item dynamic
+This attribute will be present and have the value @samp{1} if the
+varobj is a dynamic varobj. If the varobj is not a dynamic varobj,
+then this attribute will not be present.
+
+@item new_children
+If new children were added to a dynamic varobj within the selected
+update range (as set by @code{-var-set-update-range}), then they will
+be listed in this attribute.
+@end table
+
+@subsubheading Example
+
+@smallexample
+(gdb)
+-var-assign var1 3
+^done,value="3"
+(gdb)
+-var-update --all-values var1
+^done,changelist=[@{name="var1",value="3",in_scope="true",
+type_changed="false"@}]
+(gdb)
+@end smallexample
+
@subheading The @code{-var-set-frozen} Command
@findex -var-set-frozen
@anchor{-var-set-frozen}
@@ -23821,6 +23991,32 @@ Unfreezing a variable does not update it, only subsequent
(gdb)
@end smallexample
+@subheading The @code{-var-set-update-range} command
+@findex -var-set-update-range
+@anchor{-var-set-update-range}
+
+@subsubheading Synopsis
+
+@smallexample
+ -var-set-update-range @var{name} @var{from} @var{to}
+@end smallexample
+
+Set the range of children to be returned by future invocations of
+@code{-var-update}.
+
+@var{from} and @var{to} indicate the range of children to report. If
+@var{from} or @var{to} is less than zero, the range is reset and all
+children will be reported. Otherwise, children starting at @var{from}
+(zero-based) and up to and excluding @var{to} will be reported.
+
+@subsubheading Example
+
+@smallexample
+(gdb)
+-var-set-update-range V 1 2
+^done
+@end smallexample
+
@subheading The @code{-var-set-visualizer} command
@findex -var-set-visualizer
@anchor{-var-set-visualizer}
diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c
index 0cf03d9..0baaa83 100644
--- a/gdb/mi/mi-cmd-var.c
+++ b/gdb/mi/mi-cmd-var.c
@@ -41,7 +41,7 @@ static void varobj_update_one (struct varobj *var,
enum print_values print_values,
int explicit);
-static int mi_print_value_p (struct type *type, enum print_values print_values);
+static int mi_print_value_p (struct varobj *var, enum print_values print_values);
/* Print variable object VAR. The PRINT_VALUES parameter controls
if the value should be printed. The PRINT_EXPRESSION parameter
@@ -53,14 +53,19 @@ print_varobj (struct varobj *var, enum print_values print_values,
struct type *gdb_type;
char *type;
int thread_id;
+ char *display_hint;
ui_out_field_string (uiout, "name", varobj_get_objname (var));
if (print_expression)
ui_out_field_string (uiout, "exp", varobj_get_expression (var));
ui_out_field_int (uiout, "numchild", varobj_get_num_children (var));
- if (mi_print_value_p (varobj_get_gdb_type (var), print_values))
- ui_out_field_string (uiout, "value", varobj_get_value (var));
+ if (mi_print_value_p (var, print_values))
+ {
+ char *val = varobj_get_value (var);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
+ }
type = varobj_get_type (var);
if (type != NULL)
@@ -75,6 +80,16 @@ print_varobj (struct varobj *var, enum print_values print_values,
if (varobj_get_frozen (var))
ui_out_field_int (uiout, "frozen", 1);
+
+ display_hint = varobj_get_display_hint (var);
+ if (display_hint)
+ {
+ ui_out_field_string (uiout, "displayhint", display_hint);
+ xfree (display_hint);
+ }
+
+ if (varobj_pretty_printed_p (var))
+ ui_out_field_int (uiout, "dynamic", 1);
}
/* VAROBJ operations */
@@ -138,6 +153,8 @@ mi_cmd_var_create (char *command, char **argv, int argc)
print_varobj (var, PRINT_ALL_VALUES, 0 /* don't print expression */);
+ ui_out_field_int (uiout, "has_more", varobj_has_more (var, 0));
+
do_cleanups (old_cleanups);
}
@@ -223,6 +240,7 @@ mi_cmd_var_set_format (char *command, char **argv, int argc)
{
enum varobj_display_formats format;
struct varobj *var;
+ char *val;
if (argc != 2)
error (_("mi_cmd_var_set_format: Usage: NAME FORMAT."));
@@ -239,7 +257,9 @@ mi_cmd_var_set_format (char *command, char **argv, int argc)
ui_out_field_string (uiout, "format", varobj_format_string[(int) format]);
/* Report the value in the new format */
- ui_out_field_string (uiout, "value", varobj_get_value (var));
+ val = varobj_get_value (var);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
}
void
@@ -337,11 +357,12 @@ Must be: 0 or \"%s\", 1 or \"%s\", 2 or \"%s\""),
}
/* Return 1 if given the argument PRINT_VALUES we should display
- a value of type TYPE. */
+ the varobj VAR. */
static int
-mi_print_value_p (struct type *type, enum print_values print_values)
+mi_print_value_p (struct varobj *var, enum print_values print_values)
{
+ struct type *type;
if (print_values == PRINT_NO_VALUES)
return 0;
@@ -349,6 +370,10 @@ mi_print_value_p (struct type *type, enum print_values print_values)
if (print_values == PRINT_ALL_VALUES)
return 1;
+ if (varobj_pretty_printed_p (var))
+ return 1;
+
+ type = varobj_get_gdb_type (var);
if (type == NULL)
return 1;
else
@@ -369,24 +394,35 @@ mi_cmd_var_list_children (char *command, char **argv, int argc)
struct varobj *var;
VEC(varobj_p) *children;
struct varobj *child;
- struct cleanup *cleanup_children;
int numchild;
enum print_values print_values;
int ix;
+ int from, to;
char *display_hint;
- if (argc != 1 && argc != 2)
- error (_("mi_cmd_var_list_children: Usage: [PRINT_VALUES] NAME"));
+ if (argc < 1 || argc > 4)
+ error (_("mi_cmd_var_list_children: Usage: [PRINT_VALUES] NAME [FROM TO]"));
/* Get varobj handle, if a valid var obj name was specified */
- if (argc == 1)
+ if (argc == 1 || argc == 3)
var = varobj_get_handle (argv[0]);
else
var = varobj_get_handle (argv[1]);
- children = varobj_list_children (var);
- ui_out_field_int (uiout, "numchild", VEC_length (varobj_p, children));
- if (argc == 2)
+ if (argc > 2)
+ {
+ from = atoi (argv[argc - 2]);
+ to = atoi (argv[argc - 1]);
+ }
+ else
+ {
+ from = -1;
+ to = -1;
+ }
+
+ children = varobj_list_children (var, &from, &to);
+ ui_out_field_int (uiout, "numchild", to - from);
+ if (argc == 2 || argc == 4)
print_values = mi_parse_values_option (argv[0]);
else
print_values = PRINT_NO_VALUES;
@@ -398,21 +434,28 @@ mi_cmd_var_list_children (char *command, char **argv, int argc)
xfree (display_hint);
}
- if (VEC_length (varobj_p, children) == 0)
- return;
-
- if (mi_version (uiout) == 1)
- cleanup_children = make_cleanup_ui_out_tuple_begin_end (uiout, "children");
- else
- cleanup_children = make_cleanup_ui_out_list_begin_end (uiout, "children");
- for (ix = 0; VEC_iterate (varobj_p, children, ix, child); ++ix)
+ if (from < to)
{
- struct cleanup *cleanup_child;
- cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, "child");
- print_varobj (child, print_values, 1 /* print expression */);
- do_cleanups (cleanup_child);
+ struct cleanup *cleanup_children;
+ if (mi_version (uiout) == 1)
+ cleanup_children
+ = make_cleanup_ui_out_tuple_begin_end (uiout, "children");
+ else
+ cleanup_children
+ = make_cleanup_ui_out_list_begin_end (uiout, "children");
+ for (ix = from;
+ ix < to && VEC_iterate (varobj_p, children, ix, child);
+ ++ix)
+ {
+ struct cleanup *cleanup_child;
+ cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, "child");
+ print_varobj (child, print_values, 1 /* print expression */);
+ do_cleanups (cleanup_child);
+ }
+ do_cleanups (cleanup_children);
}
- do_cleanups (cleanup_children);
+
+ ui_out_field_int (uiout, "has_more", varobj_has_more (var, to));
}
void
@@ -538,16 +581,24 @@ mi_cmd_var_evaluate_expression (char *command, char **argv, int argc)
var = varobj_get_handle (argv[optind]);
if (formatFound)
- ui_out_field_string (uiout, "value", varobj_get_formatted_value (var, format));
+ {
+ char *val = varobj_get_formatted_value (var, format);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
+ }
else
- ui_out_field_string (uiout, "value", varobj_get_value (var));
+ {
+ char *val = varobj_get_value (var);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
+ }
}
void
mi_cmd_var_assign (char *command, char **argv, int argc)
{
struct varobj *var;
- char *expression;
+ char *expression, *val;
if (argc != 2)
error (_("mi_cmd_var_assign: Usage: NAME EXPRESSION."));
@@ -563,7 +614,9 @@ mi_cmd_var_assign (char *command, char **argv, int argc)
if (!varobj_set_value (var, expression))
error (_("mi_cmd_var_assign: Could not assign expression to variable object"));
- ui_out_field_string (uiout, "value", varobj_get_value (var));
+ val = varobj_get_value (var);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
}
/* Type used for parameters passing to mi_cmd_var_update_iter. */
@@ -670,6 +723,7 @@ varobj_update_one (struct varobj *var, enum print_values print_values,
for (i = 0; VEC_iterate (varobj_update_result, changes, i, r); ++i)
{
char *display_hint;
+ int from, to;
if (mi_version (uiout) > 1)
cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
@@ -678,8 +732,12 @@ varobj_update_one (struct varobj *var, enum print_values print_values,
switch (r->status)
{
case VAROBJ_IN_SCOPE:
- if (mi_print_value_p (varobj_get_gdb_type (r->varobj), print_values))
- ui_out_field_string (uiout, "value", varobj_get_value (r->varobj));
+ if (mi_print_value_p (r->varobj, print_values))
+ {
+ char *val = varobj_get_value (r->varobj);
+ ui_out_field_string (uiout, "value", val);
+ xfree (val);
+ }
ui_out_field_string (uiout, "in_scope", "true");
break;
case VAROBJ_NOT_IN_SCOPE:
@@ -699,11 +757,11 @@ varobj_update_one (struct varobj *var, enum print_values print_values,
}
if (r->type_changed)
- {
- ui_out_field_string (uiout, "new_type", varobj_get_type (r->varobj));
- ui_out_field_int (uiout, "new_num_children",
- varobj_get_num_children (r->varobj));
- }
+ ui_out_field_string (uiout, "new_type", varobj_get_type (r->varobj));
+
+ if (r->type_changed || r->children_changed)
+ ui_out_field_int (uiout, "new_num_children",
+ varobj_get_num_children (r->varobj));
display_hint = varobj_get_display_hint (var);
if (display_hint)
@@ -712,28 +770,59 @@ varobj_update_one (struct varobj *var, enum print_values print_values,
xfree (display_hint);
}
- if (r->children_changed)
- {
- int ix;
- struct varobj *child;
- struct cleanup *cleanup =
- make_cleanup_ui_out_list_begin_end (uiout, "children");
+ if (varobj_pretty_printed_p (var))
+ ui_out_field_int (uiout, "dynamic", 1);
- VEC (varobj_p)* children = varobj_list_children (r->varobj);
+ varobj_get_child_range (r->varobj, &from, &to);
+ ui_out_field_int (uiout, "has_more",
+ varobj_has_more (r->varobj, to));
- for (ix = 0; VEC_iterate (varobj_p, children, ix, child); ++ix)
+ if (r->new)
+ {
+ int j;
+ varobj_p child;
+ struct cleanup *cleanup;
+
+ cleanup = make_cleanup_ui_out_list_begin_end (uiout, "new_children");
+ for (j = 0; VEC_iterate (varobj_p, r->new, j, child); ++j)
{
struct cleanup *cleanup_child;
cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
- print_varobj (child, print_values, 1 /* print expression */);
+ print_varobj (child, print_values, 1 /* print_expression */);
do_cleanups (cleanup_child);
}
do_cleanups (cleanup);
+ VEC_free (varobj_p, r->new);
+ r->new = NULL; /* Paranoia. */
}
-
+
if (mi_version (uiout) > 1)
do_cleanups (cleanup);
}
VEC_free (varobj_update_result, changes);
}
+
+void
+mi_cmd_enable_pretty_printing (char *command, char **argv, int argc)
+{
+ if (argc != 0)
+ error (_("mi_cmd_enable_pretty_printing: no arguments allowed"));
+ varobj_enable_pretty_printing ();
+}
+
+void
+mi_cmd_var_set_update_range (char *command, char **argv, int argc)
+{
+ struct varobj *var;
+ int from, to;
+
+ if (argc != 3)
+ error (_("mi_cmd_var_set_update_range: Usage: VAROBJ FROM TO"));
+
+ var = varobj_get_handle (argv[0]);
+ from = atoi (argv[1]);
+ to = atoi (argv[2]);
+
+ varobj_set_child_range (var, from, to);
+}
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index dd3d803..8ba086c 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -52,6 +52,7 @@ struct mi_cmd mi_cmds[] =
{ "data-write-memory", { NULL, 0 }, mi_cmd_data_write_memory},
{ "data-write-register-values", { NULL, 0 }, mi_cmd_data_write_register_values},
{ "enable-timings", { NULL, 0 }, mi_cmd_enable_timings},
+ { "enable-pretty-printing", { NULL, 0 }, mi_cmd_enable_pretty_printing},
{ "environment-cd", { NULL, 0 }, mi_cmd_env_cd},
{ "environment-directory", { NULL, 0 }, mi_cmd_env_dir},
{ "environment-path", { NULL, 0 }, mi_cmd_env_path},
@@ -112,6 +113,7 @@ struct mi_cmd mi_cmds[] =
{ "var-list-children", { NULL, 0 }, mi_cmd_var_list_children},
{ "var-set-format", { NULL, 0 }, mi_cmd_var_set_format},
{ "var-set-frozen", { NULL, 0 }, mi_cmd_var_set_frozen},
+ { "var-set-update-range", { NULL, 0 }, mi_cmd_var_set_update_range },
{ "var-set-visualizer", { NULL, 0 }, mi_cmd_var_set_visualizer},
{ "var-show-attributes", { NULL, 0 }, mi_cmd_var_show_attributes},
{ "var-show-format", { NULL, 0 }, mi_cmd_var_show_format},
diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h
index 85ad0c4..dfab411 100644
--- a/gdb/mi/mi-cmds.h
+++ b/gdb/mi/mi-cmds.h
@@ -99,6 +99,8 @@ extern mi_cmd_argv_ftype mi_cmd_var_set_visualizer;
extern mi_cmd_argv_ftype mi_cmd_var_show_attributes;
extern mi_cmd_argv_ftype mi_cmd_var_show_format;
extern mi_cmd_argv_ftype mi_cmd_var_update;
+extern mi_cmd_argv_ftype mi_cmd_enable_pretty_printing;
+extern mi_cmd_argv_ftype mi_cmd_var_set_update_range;
/* Description of a single command. */
diff --git a/gdb/testsuite/gdb.mi/gdb701.exp b/gdb/testsuite/gdb.mi/gdb701.exp
index d4acdc2..244c731 100644
--- a/gdb/testsuite/gdb.mi/gdb701.exp
+++ b/gdb/testsuite/gdb.mi/gdb701.exp
@@ -54,7 +54,7 @@ mi_gdb_test "-var-list-children fooPtr" \
foreach i [list x y z] {
mi_gdb_test "-var-list-children fooPtr.$i" \
- "(&\".*\"\r\n)*\\^done,numchild=\"0\"" \
+ "(&\".*\"\r\n)*\\^done,numchild=\"0\",has_more=\"0\"" \
"list children of fooPtr.$i"
}
diff --git a/gdb/testsuite/gdb.mi/mi-break.exp b/gdb/testsuite/gdb.mi/mi-break.exp
index 619727d..8d06c0e 100644
--- a/gdb/testsuite/gdb.mi/mi-break.exp
+++ b/gdb/testsuite/gdb.mi/mi-break.exp
@@ -175,7 +175,7 @@ proc test_error {} {
# containing function call, the internal breakpoint created to handle
# function call would be reported, messing up MI output.
mi_gdb_test "-var-create V * return_1()" \
- "\\^done,name=\"V\",numchild=\"0\",value=\"1\",type=\"int\"" \
+ "\\^done,name=\"V\",numchild=\"0\",value=\"1\",type=\"int\",has_more=\"0\"" \
"create varobj for function call"
mi_gdb_test "-var-update *" \
diff --git a/gdb/testsuite/gdb.mi/mi-var-block.exp b/gdb/testsuite/gdb.mi/mi-var-block.exp
index 8806848..93ded26 100644
--- a/gdb/testsuite/gdb.mi/mi-var-block.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-block.exp
@@ -74,7 +74,7 @@ mi_step_to "do_block_tests" "" "var-cmd.c" \
# Test: c_variable-3.4
# Desc: check foo, cb changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"foo\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"cb\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"foo\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"cb\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: cb foo changed"
# step to "foo = 321;"
diff --git a/gdb/testsuite/gdb.mi/mi-var-child.exp b/gdb/testsuite/gdb.mi/mi-var-child.exp
index 1f4bdc6..eb6c456 100644
--- a/gdb/testsuite/gdb.mi/mi-var-child.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-child.exp
@@ -680,7 +680,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.2
# Desc: check that integer changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.integer\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.integer"
# Step over:
@@ -693,7 +693,7 @@ mi_execute_to "exec-step 3" "end-stepping-range" do_children_tests {} ".*${srcfi
# Test: c_variable-5.3
# Desc: check that char_ptr changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.char_ptr"
# Step over "struct_declarations.int_ptr_ptr = &foo;"
@@ -703,7 +703,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.4
# Desc: check that int_ptr_ptr and children changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars int_ptr_ptr and children changed"
# Step over "weird->long_array[0] = 1234;"
@@ -713,7 +713,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.5
# Desc: check that long_array[0] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.0\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.0\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.0 changed"
# Step over "struct_declarations.long_array[1] = 2345;"
@@ -723,7 +723,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.6
# Desc: check that long_array[1] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.1\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.1\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.1 changed"
# Step over "weird->long_array[2] = 3456;"
@@ -733,7 +733,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.7
# Desc: check that long_array[2] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.2\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.2\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.2 changed"
# Step over:
@@ -752,7 +752,7 @@ mi_execute_to "exec-step 7" "end-stepping-range" do_children_tests {} ".*${srcfi
# Test: c_variable-5.8
# Desc: check that long_array[3-9] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.3\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.4\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.5\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.6\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.7\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.8\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.9\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.3\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.4\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.5\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.6\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.7\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.8\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.9\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.3-9 changed"
@@ -763,7 +763,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.9
# Desc: check that func_ptr changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.func_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.func_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.func_ptr changed"
# Step over "struct_declarations.long_array[10] = 3456";
@@ -771,7 +771,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
[expr $line_dct_nothing + 2] "step \$line_dct_nothing + 2"
mi_gdb_test "-var-update --no-values *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.10\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.10\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.10 changed, don't print values."
# Step over "struct_declarations.long_array[11] = 5678";
@@ -780,7 +780,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
$line_dct_a0_0 "step \$line_dct_a0_0"
mi_gdb_test "-var-update --all-values *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.11\",value=\"5678\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.11\",value=\"5678\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.11 changed, print values."
mi_list_varobj_children {struct_declarations.long_array --all-values} {
@@ -1121,7 +1121,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.47
# Desc: check that psnp->char_ptr (and [0].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr.\\*\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr.\\*\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->char_ptr (and 0.char_ptr) changed"
# Step over "snp1.char_ptr = &c3;"
@@ -1131,7 +1131,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.48
# Desc: check that psnp->next->char_ptr (and [1].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr.\\*\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr.\\*\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->char_ptr (and 1.char_ptr) changed"
@@ -1142,7 +1142,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.49
# Desc: check that psnp->next->next->char_ptr (and [2].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->next->char_ptr (and 2.char_ptr) changed"
@@ -1153,7 +1153,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.50
# Desc: check that psnp->long_ptr (and [0].long_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->long_ptr (and 0.long_ptr) changed"
@@ -1181,7 +1181,7 @@ mi_step_to do_children_tests {} ".*${srcfile}" \
# Test: c_variable-5.52
# Desc: check that psnp->next->next->long_ptr (and [2].long_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.long_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->next->long_ptr (and 2.long_ptr) changed"
mi_prepare_inline_tests $srcfile
diff --git a/gdb/testsuite/gdb.mi/mi-var-cmd.exp b/gdb/testsuite/gdb.mi/mi-var-cmd.exp
index ad2e55c..6efb333 100644
--- a/gdb/testsuite/gdb.mi/mi-var-cmd.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-cmd.exp
@@ -146,7 +146,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" $line_dlt_linteger "step at do_local
# Test: c_variable-2.2
# Desc: check whether only linteger changed values
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: linteger changed"
# Step over "lpinteger = &linteger;"
@@ -155,7 +155,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 1] "step
# Test: c_variable-2.3
# Desc: check whether only lpinteger changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpinteger changed"
# Step over "lcharacter = 'a';"
@@ -164,7 +164,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 2] "step
# Test: c_variable-2.4
# Desc: check whether only lcharacter changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lcharacter changed"
# Step over "lpcharacter = &lcharacter;"
@@ -173,7 +173,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 3] "step
# Test: c_variable-2.5
# Desc: check whether only lpcharacter changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpcharacter changed"
@@ -195,7 +195,7 @@ mi_execute_to "exec-step 9" "end-stepping-range" "do_locals_tests" "" \
# Desc: check whether llong, lplong, lfloat, lpfloat, ldouble, lpdouble, lsimple.integer,
# lsimple.unsigned_character lsimple.integer lsimple.character changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpdouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lplong\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpdouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lplong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: many changed"
# Step over:
@@ -212,7 +212,7 @@ mi_execute_to "exec-step 4" "end-stepping-range" "do_locals_tests" "" \
# Test: c_variable-2.7
# Desc: check whether (lsimple.signed_character, lsimple.char_ptr) lpsimple, func changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"func\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpsimple\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"func\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpsimple\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: func and lpsimple changed"
# Step over
@@ -234,7 +234,7 @@ mi_execute_to "exec-step 8" "end-stepping-range" "do_locals_tests" "" \
# Note: this test also checks that lpsimple->integer and lsimple.integer have
# changed (they are the same)
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lsimple and others changed"
@@ -257,7 +257,7 @@ mi_gdb_test "-var-assign linteger 3333" \
# change.
set lpchar_update "\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\},"
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[($lpchar_update)?\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[($lpchar_update)?\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: linteger changed after assign"
mi_gdb_test "-var-assign linteger 3333" \
@@ -277,7 +277,7 @@ mi_gdb_test "-var-assign lpinteger \"&linteger + 3\"" \
"assign to lpinteger"
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpinteger changed after assign"
mi_gdb_test "-var-update *" \
@@ -377,7 +377,7 @@ mi_gdb_test "-var-update *" \
"assign same value to func (update)"
mi_gdb_test "-var-create array_ptr * array_ptr" \
- "\\^done,name=\"array_ptr\",numchild=\"1\",value=\"$hex\",type=\"int \\*\"" \
+ "\\^done,name=\"array_ptr\",numchild=\"1\",value=\"$hex\",type=\"int \\*\",has_more=\"0\"" \
"create global variable array_ptr"
mi_gdb_test "-var-assign array_ptr array2" \
@@ -385,7 +385,7 @@ mi_gdb_test "-var-assign array_ptr array2" \
"assign array to pointer"
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"array_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"array_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"assign array to pointer (update)"
mi_gdb_test "-var-assign array_ptr array2" \
@@ -439,7 +439,7 @@ mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\
# Test: c_variable-2.13
# Desc: change subroutine1 local i
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"i\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"i\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: i changed"
mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\}" \
@@ -448,7 +448,7 @@ mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\
# Test: c_variable-2.14
# Desc: change do_locals_tests local llong
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: llong changed"
set line_dlt_call_subroutine1 [gdb_get_line_number "subroutine1 (linteger, &llong);"]
@@ -458,7 +458,7 @@ mi_next_to "do_locals_tests" "" "var-cmd.c" \
# Test: c_variable-2.15
# Desc: check for out of scope subroutine1 locals
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\,type_changed=\"false\"},\{name=\"i\",in_scope=\"false\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\,type_changed=\"false\",has_more=\"0\"},\{name=\"i\",in_scope=\"false\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: all now out of scope"
# Done with locals/globals tests. Erase all variables
@@ -550,14 +550,14 @@ mi_gdb_test "-var-create selected_a @ a" \
mi_continue_to incr_a
mi_gdb_test "-var-update selected_a" \
- "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"char\",new_num_children=\"0\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"char\",new_num_children=\"0\",has_more=\"0\"\}\\\]" \
"update selected_a in incr_a"
mi_next "step a line in incr_a"
mi_next "return from incr_a to do_special_tests"
mi_gdb_test "-var-update selected_a" \
- "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"int\",new_num_children=\"0\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"int\",new_num_children=\"0\",has_more=\"0\"\}\\\]" \
"update selected_a in do_special_tests"
mi_gdb_test "-file-exec-and-symbols ${binfile}" "\\^done" \
@@ -596,7 +596,7 @@ mi_check_varobj_value F 7 "check F inside callee"
# A varobj we fail to read during -var-update should be considered
# out of scope.
mi_gdb_test "-var-create null_ptr * **0" \
- {\^done,name="null_ptr",numchild="0",value=".*",type="int"} \
+ {\^done,name="null_ptr",numchild="0",value=".*",type="int",has_more="0"} \
"create null_ptr"
# Allow this to succeed, if address zero is readable, although it
@@ -644,7 +644,7 @@ mi_check_varobj_value "L" "{...}" "in-and-out-of-scope: check initial value"
mi_runto main
mi_gdb_test "-var-update L" \
- {\^done,changelist=\[{name="L",in_scope="false",type_changed="false"}\]} \
+ {\^done,changelist=\[{name="L",in_scope="false",type_changed="false",has_more="0"}\]} \
"in-and-out-of-scope: out of scope now"
mi_gdb_test "-var-update L" \
@@ -654,7 +654,7 @@ mi_gdb_test "-var-update L" \
mi_continue_to do_locals_tests
mi_gdb_test "-var-update L" \
- {\^done,changelist=\[{name="L",in_scope="true",type_changed="false"}\]} \
+ {\^done,changelist=\[{name="L",in_scope="true",type_changed="false",has_more="0"}\]} \
"in-and-out-of-scope: in scope now"
mi_gdb_test "-var-update L" \
diff --git a/gdb/testsuite/gdb.mi/mi-var-display.exp b/gdb/testsuite/gdb.mi/mi-var-display.exp
index 4b02e50..faa9172 100644
--- a/gdb/testsuite/gdb.mi/mi-var-display.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-display.exp
@@ -558,7 +558,7 @@ mi_gdb_test "-var-info-num-children e" \
# Test: c_variable-7.55
# Desc: children of e
mi_gdb_test "-var-list-children e" \
- "\\^done,numchild=\"0\"" \
+ "\\^done,numchild=\"0\",has_more=\"0\"" \
"get children of e"
# Test: c_variable-7.60
@@ -600,7 +600,7 @@ mi_gdb_test "-var-info-num-children anone" \
# Test: c_variable-7.75
# Desc: children of anone
mi_gdb_test "-var-list-children anone" \
- "\\^done,numchild=\"0\"" \
+ "\\^done,numchild=\"0\",has_more=\"0\"" \
"get children of anone"
diff --git a/gdb/testsuite/gdb.mi/mi-var-invalidate.exp b/gdb/testsuite/gdb.mi/mi-var-invalidate.exp
index 05d46fa..4b95674 100644
--- a/gdb/testsuite/gdb.mi/mi-var-invalidate.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-invalidate.exp
@@ -72,7 +72,7 @@ mi_runto main
# Check local variable is "invalid".
mi_gdb_test "-var-update linteger" \
- "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"invalid\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"invalid\",has_more=\"0\"\}\\\]" \
"linteger not anymore in scope due to binary changes"
mi_gdb_test "-var-info-type linteger" \
@@ -97,7 +97,7 @@ mi_delete_breakpoints
mi_gdb_load ${binfile2}
# Check local variable are "invalid"
mi_gdb_test "-var-update linteger" \
- "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"invalid\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"invalid\",has_more=\"0\"\}\\\]" \
"linteger not valid anymore due to binary changes"
mi_gdb_test "-var-info-type linteger" \
@@ -106,7 +106,7 @@ mi_gdb_test "-var-info-type linteger" \
# Check global variable are still correct.
mi_gdb_test "-var-update global_simple" \
- "\\^done,changelist=\\\[\{name=\"global_simple\",in_scope=\"invalid\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"global_simple\",in_scope=\"invalid\",has_more=\"0\"\}\\\]" \
"global_simple not anymore in scope due to binary changes"
mi_gdb_test "-var-info-type global_simple" \
diff --git a/gdb/testsuite/gdb.mi/mi2-var-block.exp b/gdb/testsuite/gdb.mi/mi2-var-block.exp
index 6bcfea3..9b3d08f 100644
--- a/gdb/testsuite/gdb.mi/mi2-var-block.exp
+++ b/gdb/testsuite/gdb.mi/mi2-var-block.exp
@@ -74,7 +74,7 @@ mi_step_to "do_block_tests" "" "var-cmd.c" \
# Test: c_variable-3.4
# Desc: check foo, cb changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"foo\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"cb\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"foo\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"cb\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: cb foo changed"
# step to "foo = 321;"
diff --git a/gdb/testsuite/gdb.mi/mi2-var-child.exp b/gdb/testsuite/gdb.mi/mi2-var-child.exp
index 161b34f..0f9b4d4 100644
--- a/gdb/testsuite/gdb.mi/mi2-var-child.exp
+++ b/gdb/testsuite/gdb.mi/mi2-var-child.exp
@@ -1,4 +1,4 @@
-# Copyright 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
+# Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2009 Free Software Foundation
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -680,7 +680,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.2
# Desc: check that integer changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.integer\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.integer"
# Step over:
@@ -693,7 +693,7 @@ mi_execute_to "exec-step 3" "end-stepping-range" do_children_tests {} {.*var-cmd
# Test: c_variable-5.3
# Desc: check that char_ptr changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.char_ptr"
# Step over "struct_declarations.int_ptr_ptr = &foo;"
@@ -703,7 +703,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.4
# Desc: check that int_ptr_ptr and children changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars int_ptr_ptr and children changed"
# Step over "weird->long_array[0] = 1234;"
@@ -713,7 +713,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.5
# Desc: check that long_array[0] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.0\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.0\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.0 changed"
# Step over "struct_declarations.long_array[1] = 2345;"
@@ -723,7 +723,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.6
# Desc: check that long_array[1] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.1\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.1\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.1 changed"
# Step over "weird->long_array[2] = 3456;"
@@ -733,7 +733,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.7
# Desc: check that long_array[2] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.2\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.2\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.2 changed"
# Step over:
@@ -752,7 +752,7 @@ mi_execute_to "exec-step 7" "end-stepping-range" do_children_tests {} {.*var-cmd
# Test: c_variable-5.8
# Desc: check that long_array[3-9] changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.3\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.4\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.5\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.6\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.7\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.8\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"struct_declarations.long_array.9\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.long_array.3\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.4\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.5\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.6\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.7\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.8\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"struct_declarations.long_array.9\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.long_array.3-9 changed"
@@ -764,7 +764,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.9
# Desc: check that func_ptr changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"struct_declarations.func_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"struct_declarations.func_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars struct_declarations.func_ptr changed"
# Delete all variables
@@ -1075,7 +1075,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.47
# Desc: check that psnp->char_ptr (and [0].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr.\\*\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr.\\*\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->char_ptr (and 0.char_ptr) changed"
# Step over "snp1.char_ptr = &c3;"
@@ -1085,7 +1085,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.48
# Desc: check that psnp->next->char_ptr (and [1].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr.\\*\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr.\\*\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->char_ptr (and 1.char_ptr) changed"
@@ -1096,7 +1096,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.49
# Desc: check that psnp->next->next->char_ptr (and [2].char_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.char_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.char_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->next->char_ptr (and 2.char_ptr) changed"
@@ -1107,7 +1107,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.50
# Desc: check that psnp->long_ptr (and [0].long_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->long_ptr (and 0.long_ptr) changed"
@@ -1120,7 +1120,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Why does this have a FIXME?
setup_xfail *-*-*
mi_gdb_test "-var-update *" \
- "FIXME\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.long_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "FIXME\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->long_ptr (and 1.long_ptr) changed"
clear_xfail *-*-*
@@ -1135,7 +1135,7 @@ mi_step_to do_children_tests {} {.*var-cmd.c} \
# Test: c_variable-5.52
# Desc: check that psnp->next->next->long_ptr (and [2].long_ptr) changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.long_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.long_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars psnp->next->next->long_ptr (and 2.long_ptr) changed"
diff --git a/gdb/testsuite/gdb.mi/mi2-var-cmd.exp b/gdb/testsuite/gdb.mi/mi2-var-cmd.exp
index dda77bb..e900d14 100644
--- a/gdb/testsuite/gdb.mi/mi2-var-cmd.exp
+++ b/gdb/testsuite/gdb.mi/mi2-var-cmd.exp
@@ -126,11 +126,6 @@ mi_gdb_test "-var-create int * int" \
"&\"Attempt to use a type name as an expression.\\\\n\".*\\^error,msg=\"mi_cmd_var_create: unable to create variable object\"" \
"create int"
-# The number 0 must be an invalid frame address and linteger a local variable.
-mi_gdb_test "-var-create invalidframe 0 linteger" \
- "\\^error,msg=\"Failed to find the specified frame\"" \
- "create variable with invalid FRAME-ADDR"
-
##### #####
# #
@@ -151,7 +146,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" $line_dlt_linteger "step at do_local
# Test: c_variable-2.2
# Desc: check whether only linteger changed values
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: linteger changed"
# Step over "lpinteger = &linteger;"
@@ -160,7 +155,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 1] "step
# Test: c_variable-2.3
# Desc: check whether only lpinteger changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpinteger changed"
# Step over "lcharacter = 'a';"
@@ -169,7 +164,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 2] "step
# Test: c_variable-2.4
# Desc: check whether only lcharacter changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lcharacter changed"
# Step over "lpcharacter = &lcharacter;"
@@ -178,7 +173,7 @@ mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 3] "step
# Test: c_variable-2.5
# Desc: check whether only lpcharacter changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpcharacter changed"
@@ -200,7 +195,7 @@ mi_execute_to "exec-step 9" "end-stepping-range" "do_locals_tests" "" \
# Desc: check whether llong, lplong, lfloat, lpfloat, ldouble, lpdouble, lsimple.integer,
# lsimple.unsigned_character lsimple.integer lsimple.character changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpdouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lplong\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpdouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lplong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: many changed"
# Step over:
@@ -217,7 +212,7 @@ mi_execute_to "exec-step 4" "end-stepping-range" "do_locals_tests" "" \
# Test: c_variable-2.7
# Desc: check whether (lsimple.signed_character, lsimple.char_ptr) lpsimple, func changed
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"func\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpsimple\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"func\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpsimple\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: func and lpsimple changed"
# Step over
@@ -239,7 +234,7 @@ mi_execute_to "exec-step 8" "end-stepping-range" "do_locals_tests" "" \
# Note: this test also checks that lpsimple->integer and lsimple.integer have
# changed (they are the same)
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\"\},\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"ldouble\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lfloat\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\},\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lsimple and others changed"
@@ -262,7 +257,7 @@ mi_gdb_test "-var-assign linteger 3333" \
# change.
set lpchar_update "\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\},"
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[($lpchar_update)?\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[($lpchar_update)?\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: linteger changed after assign"
mi_gdb_test "-var-assign linteger 3333" \
@@ -282,7 +277,7 @@ mi_gdb_test "-var-assign lpinteger \"&linteger + 3\"" \
"assign to lpinteger"
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: lpinteger changed after assign"
mi_gdb_test "-var-update *" \
@@ -407,7 +402,7 @@ mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\
# Test: c_variable-2.13
# Desc: change subroutine1 local i
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"i\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"i\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: i changed"
mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\}" \
@@ -416,7 +411,7 @@ mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\
# Test: c_variable-2.14
# Desc: change do_locals_tests local llong
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"llong\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: llong changed"
set line_dlt_call_subroutine1 [gdb_get_line_number "subroutine1 (linteger, &llong);"]
@@ -426,7 +421,7 @@ mi_next_to "do_locals_tests" "" "var-cmd.c" \
# Test: c_variable-2.15
# Desc: check for out of scope subroutine1 locals
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\,type_changed=\"false\"},\{name=\"i\",in_scope=\"false\",type_changed=\"false\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\,type_changed=\"false\",has_more=\"0\"},\{name=\"i\",in_scope=\"false\",type_changed=\"false\",has_more=\"0\"\}\\\]" \
"update all vars: all now out of scope"
# Done with locals/globals tests. Erase all variables
@@ -518,14 +513,14 @@ mi_gdb_test "-var-create selected_a @ a" \
mi_continue_to incr_a
mi_gdb_test "-var-update selected_a" \
- "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"char\",new_num_children=\"0\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"char\",new_num_children=\"0\"\,has_more=\"0\"}\\\]" \
"update selected_a in incr_a"
mi_next "step a line in incr_a"
mi_next "return from incr_a to do_special_tests"
mi_gdb_test "-var-update selected_a" \
- "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"int\",new_num_children=\"0\"\}\\\]" \
+ "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"int\",new_num_children=\"0\",has_more=\"0\"\}\\\]" \
"update selected_a in do_special_tests"
mi_gdb_test "-file-exec-and-symbols ${binfile}" "\\^done" \
diff --git a/gdb/testsuite/gdb.mi/mi2-var-display.exp b/gdb/testsuite/gdb.mi/mi2-var-display.exp
index d6ce673..17e208a 100644
--- a/gdb/testsuite/gdb.mi/mi2-var-display.exp
+++ b/gdb/testsuite/gdb.mi/mi2-var-display.exp
@@ -557,7 +557,7 @@ mi_gdb_test "-var-info-num-children e" \
# Test: c_variable-7.55
# Desc: children of e
mi_gdb_test "-var-list-children e" \
- "\\^done,numchild=\"0\"" \
+ "\\^done,numchild=\"0\",has_more=\"0\"" \
"get children of e"
# Test: c_variable-7.60
@@ -599,7 +599,7 @@ mi_gdb_test "-var-info-num-children anone" \
# Test: c_variable-7.75
# Desc: children of anone
mi_gdb_test "-var-list-children anone" \
- "\\^done,numchild=\"0\"" \
+ "\\^done,numchild=\"0\",has_more=\"0\"" \
"get children of anone"
diff --git a/gdb/testsuite/gdb.python/py-mi.exp b/gdb/testsuite/gdb.python/py-mi.exp
index d3f44b2..30d6f32 100644
--- a/gdb/testsuite/gdb.python/py-mi.exp
+++ b/gdb/testsuite/gdb.python/py-mi.exp
@@ -48,23 +48,53 @@ mi_gdb_test "python execfile ('${srcdir}/${subdir}/${testfile}.py')" ""
mi_continue_to_line [gdb_get_line_number {MI breakpoint here} ${testfile}.c] \
"step to breakpoint"
-mi_create_floating_varobj container c "create container varobj"
+mi_create_dynamic_varobj container c \
+ "create container varobj, no pretty-printing"
+
+mi_list_varobj_children container {
+ { container.name name 1 string }
+ { container.len len 0 int }
+ { container.elements elements 1 "int ." }
+} "examine container children=0, no pretty-printing"
+
+mi_delete_varobj container "delete varobj"
+
+mi_gdb_test "-enable-pretty-printing" ""
+
+mi_create_varobj_checked string string_1 \
+ "struct string_repr" \
+ "create string_1 varobj"
+
+mi_gdb_test "-data-evaluate-expression \"string_1 = string_2\"" ".*" \
+ "assign string_1 from string_2"
+
+mi_gdb_test "-var-update string" \
+ "\\^done,changelist=\\\[{name=\"string\",in_scope=\"true\",type_changed=\"false\",dynamic=\"1\",has_more=\"0\"}\\\]" \
+ "update string varobj after assignment"
+
+mi_create_dynamic_varobj container c \
+ "create container varobj"
mi_list_varobj_children container {
} "examine container children=0"
mi_next "next over update 1"
-mi_varobj_update_dynamic container {
- { {container.\[0\]} {\[0\]} 0 int }
-} "varobj update 1"
+mi_varobj_update_dynamic container "varobj update 1" {
+ type_changed false new_num_children 1 dynamic 1 has_more 0
+} {
+} {
+ { name {container.\[0\]} exp {\[0\]} numchild 0 type int thread-id 1 }
+}
mi_next "next over update 2"
-mi_varobj_update_dynamic container {
- { {container.\[0\]} {\[0\]} 0 int }
- { {container.\[1\]} {\[1\]} 0 int }
-} "varobj update 2"
+mi_varobj_update_dynamic container "varobj update 2" {
+ type_changed false new_num_children 2 dynamic 1 has_more 0
+} {
+} {
+ { name {container.\[1\]} exp {\[1\]} numchild 0 type int thread-id 1 }
+}
mi_gdb_test "-var-set-visualizer container None" \
"\\^done" \
@@ -78,19 +108,124 @@ mi_gdb_test "-var-set-visualizer container gdb.default_visualizer" \
"\\^done" \
"choose default visualizer"
-mi_varobj_update_dynamic container {
- { {container.\[0\]} {\[0\]} 0 int }
- { {container.\[1\]} {\[1\]} 0 int }
-} "varobj update after choosing default"
+mi_varobj_update_dynamic container "varobj update after choosing default" {
+ type_changed false new_num_children 2 dynamic 1 has_more 0
+} {
+} {
+ { name {container.\[0\]} exp {\[0\]} numchild 0 type int thread-id 1 }
+ { name {container.\[1\]} exp {\[1\]} numchild 0 type int thread-id 1 }
+}
mi_gdb_test "-var-set-visualizer container ContainerPrinter" \
"\\^done" \
"choose visualizer using expression"
-mi_varobj_update_dynamic container {
+mi_varobj_update_dynamic container \
+ "varobj update after choosing via expression" {
+ type_changed false new_num_children 2 dynamic 1 has_more 0
+ } {
+ } {
+ { name {container.\[0\]} exp {\[0\]} numchild 0 type int thread-id 1 }
+ { name {container.\[1\]} exp {\[1\]} numchild 0 type int thread-id 1 }
+ }
+
+mi_list_varobj_children_range container 1 2 2 {
+ { {container.\[1\]} {\[1\]} 0 int }
+} "list varobj children after selecting child range"
+
+mi_list_varobj_children_range container -1 -1 2 {
{ {container.\[0\]} {\[0\]} 0 int }
{ {container.\[1\]} {\[1\]} 0 int }
-} "varobj update after choosing via expression"
+} "list varobj children after resetting child range"
+
+mi_next "next over update 3"
+
+mi_gdb_test "-var-set-update-range container 0 1" \
+ "\\^done" \
+ "set update range"
+
+# This should truncate the list.
+mi_list_varobj_children container {
+ { {container.\[0\]} {\[0\]} 0 int }
+} "list children after setting update range"
+
+# This should return just the items in [1,2).
+mi_list_varobj_children_range container 1 2 2 {
+ { {container.\[1\]} {\[1\]} 0 int }
+} "list selected children after setting range"
+
+# This should not be affected by the previous list-children request.
+mi_list_varobj_children container {
+ { {container.\[0\]} {\[0\]} 0 int }
+} "list children after listing selected range"
+
+mi_next "next over update 4"
+
+# This should only show the first child, because the update range has
+# been set.
+mi_varobj_update_dynamic container \
+ "update after next with restricted range" {
+ type_changed false new_num_children 1 dynamic 1 has_more 1
+ } {
+ { name {container.\[0\]} in_scope true type_changed false dynamic 1 has_more 0 }
+ } {
+ }
+
+mi_gdb_test "-var-set-update-range container 3 4" \
+ "\\^done" \
+ "set update range with non-zero start"
+
+# Elements were updated but should not be reported.
+mi_varobj_update_dynamic container \
+ "update varobj with change outside selected range" {
+ type_changed false new_num_children 3 dynamic 1 has_more 0
+ } {
+ } {
+ }
+
+mi_next "next over update 5"
+
+# Regression test: examine an object that has no children, then update
+# it to ensure that we don't print the children.
+mi_create_dynamic_varobj container2 c2 \
+ "create second container varobj"
+
+mi_gdb_test "-var-update container2" \
+ "\\^done,changelist=.." \
+ "update varobj, no children requested"
+
+mi_next "next over update 6"
+
+# Now container2 has an element -- and an update should mention that
+# it has_more. But, because we did not request children, we still
+# should not actually see them.
+mi_varobj_update_dynamic container2 \
+ "update varobj 2, no children requested" {
+ type_changed false dynamic 1 has_more 1
+ } {} {}
+
+mi_continue_to_line \
+ [gdb_get_line_number {MI outer breakpoint here} ${testfile}.c] \
+ "step to outer breakpoint"
+
+mi_create_dynamic_varobj outer outer \
+ "create outer varobj"
+
+mi_list_varobj_children outer {
+ { outer.s s 2 "struct substruct" }
+ { outer.x x 0 "int" }
+} "list children of outer"
+
+mi_list_varobj_children outer.s {
+ { outer.s.a a 0 int }
+ { outer.s.b b 0 int }
+} "list children of outer.s"
+
+mi_next "next over outer update"
+
+mi_gdb_test "-var-update outer" \
+ ".done,changelist=.{name=\"outer.s.a\",in_scope=\"true\",type_changed=\"false\",dynamic=\"1\",has_more=\"0\"}." \
+ "update after updating element of outer"
mi_continue_to_line \
[gdb_get_line_number {Another MI breakpoint} ${testfile}.c] \
diff --git a/gdb/testsuite/gdb.python/py-prettyprint.c b/gdb/testsuite/gdb.python/py-prettyprint.c
index 3cafc48..7f16400 100644
--- a/gdb/testsuite/gdb.python/py-prettyprint.c
+++ b/gdb/testsuite/gdb.python/py-prettyprint.c
@@ -15,6 +15,8 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
+#include <string.h>
+
struct s
{
int a;
@@ -80,6 +82,29 @@ class Derived : public Vbase1, public Vbase2, public Vbase3
#endif
+struct substruct {
+ int a;
+ int b;
+};
+
+struct outerstruct {
+ struct substruct s;
+ int x;
+};
+
+struct outerstruct
+substruct_test (void)
+{
+ struct outerstruct outer;
+ outer.s.a = 0;
+ outer.s.b = 0;
+ outer.x = 0;
+
+ outer.s.a = 3; /* MI outer breakpoint here */
+
+ return outer;
+}
+
typedef struct string_repr
{
struct whybother
@@ -148,6 +173,14 @@ void do_nothing(void)
c = 23; /* Another MI breakpoint */
}
+struct nullstr
+{
+ char *s;
+};
+
+struct string_repr string_1 = { { "one" } };
+struct string_repr string_2 = { { "two" } };
+
int
main ()
{
@@ -155,11 +188,15 @@ main ()
struct ss ssa[2];
string x = make_string ("this is x");
zzz_type c = make_container ("container");
+ zzz_type c2 = make_container ("container2");
const struct string_repr cstring = { { "const string" } };
+ /* Clearing by being `static' could invoke an other GDB C++ bug. */
+ struct nullstr nullstr;
init_ss(&ss, 1, 2);
init_ss(ssa+0, 3, 4);
init_ss(ssa+1, 5, 6);
+ memset (&nullstr, 0, sizeof nullstr);
struct ns ns;
ns.null_str = "embedded\0null\0string";
@@ -193,6 +230,14 @@ main ()
add_item (&c, 72);
#ifdef MI
+ add_item (&c, 1011);
+ c.elements[0] = 1023;
+ c.elements[0] = 2323;
+
+ add_item (&c2, 2222);
+ add_item (&c2, 3333);
+
+ substruct_test ();
do_nothing ();
#endif
diff --git a/gdb/testsuite/gdb.python/py-prettyprint.py b/gdb/testsuite/gdb.python/py-prettyprint.py
index bf009a1..2f070d8 100644
--- a/gdb/testsuite/gdb.python/py-prettyprint.py
+++ b/gdb/testsuite/gdb.python/py-prettyprint.py
@@ -92,6 +92,13 @@ class pp_vbase1:
def to_string (self):
return "pp class name: " + self.val.type.tag
+class pp_nullstr:
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ return self.val['s'].string(gdb.parameter('target-charset'))
+
class pp_ns:
"Print a std::basic_string of some kind"
@@ -105,11 +112,24 @@ class pp_ns:
def display_hint (self):
return 'string'
+class pp_outer:
+ "Print struct outer"
+
+ def __init__ (self, val):
+ self.val = val
+
+ def to_string (self):
+ return "x = %s" % self.val['x']
+
+ def children (self):
+ yield 's', self.val['s']
+ yield 'x', self.val['x']
+
def lookup_function (val):
"Look-up and return a pretty-printer that can print val."
# Get the type.
- type = val.type;
+ type = val.type
# If it points to a reference, get the reference.
if type.code == gdb.TYPE_CODE_REF:
@@ -148,6 +168,9 @@ def register_pretty_printers ():
pretty_printers_dict[re.compile ('^VirtualTest$')] = pp_multiple_virtual
pretty_printers_dict[re.compile ('^Vbase1$')] = pp_vbase1
+
+ pretty_printers_dict[re.compile ('^struct nullstr$')] = pp_nullstr
+ pretty_printers_dict[re.compile ('^nullstr$')] = pp_nullstr
# Note that we purposely omit the typedef names here.
# Printer lookup is based on canonical name.
@@ -160,6 +183,10 @@ def register_pretty_printers ():
pretty_printers_dict[re.compile ('^struct ns$')] = pp_ns
pretty_printers_dict[re.compile ('^ns$')] = pp_ns
+
+ pretty_printers_dict[re.compile ('^struct outerstruct$')] = pp_outer
+ pretty_printers_dict[re.compile ('^outerstruct$')] = pp_outer
+
pretty_printers_dict = {}
register_pretty_printers ()
diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
index e691232..167a02c 100644
--- a/gdb/testsuite/lib/mi-support.exp
+++ b/gdb/testsuite/lib/mi-support.exp
@@ -1195,13 +1195,13 @@ proc mi_list_breakpoints { expected test } {
# Name cannot be "-".
proc mi_create_varobj { name expression testname } {
mi_gdb_test "-var-create $name * $expression" \
- "\\^done,name=\"$name\",numchild=\"\[0-9\]+\",value=\".*\",type=.*" \
+ "\\^done,name=\"$name\",numchild=\"\[0-9\]+\",value=\".*\",type=.*,has_more=\"0\"" \
$testname
}
proc mi_create_floating_varobj { name expression testname } {
mi_gdb_test "-var-create $name @ $expression" \
- "\\^done,name=\"$name\",numchild=\"\[0-9\]+\",value=\".*\",type=.*" \
+ "\\^done,name=\"$name\",numchild=\"\(-1\|\[0-9\]+\)\",value=\".*\",type=.*" \
$testname
}
@@ -1214,6 +1214,14 @@ proc mi_create_varobj_checked { name expression type testname } {
$testname
}
+# Same as mi_create_floating_varobj, but assumes the test is creating
+# a dynamic varobj that has children, so the value must be "{...}".
+proc mi_create_dynamic_varobj {name expression testname} {
+ mi_gdb_test "-var-create $name @ $expression" \
+ "\\^done,name=\"$name\",numchild=\"\(-1\|\[0-9\]+\)\",value=\"{\\.\\.\\.}\",type=.*" \
+ $testname
+}
+
# Deletes the specified NAME.
proc mi_delete_varobj { name testname } {
mi_gdb_test "-var-delete $name" \
@@ -1229,7 +1237,7 @@ proc mi_varobj_update { name expected testname } {
set er "\\^done,changelist=\\\["
set first 1
foreach item $expected {
- set v "{name=\"$item\",in_scope=\"true\",type_changed=\"false\"}"
+ set v "{name=\"$item\",in_scope=\"true\",type_changed=\"false\",has_more=\".\"}"
if {$first == 1} {
set er "$er$v"
set first 0
@@ -1244,22 +1252,70 @@ proc mi_varobj_update { name expected testname } {
}
proc mi_varobj_update_with_type_change { name new_type new_children testname } {
- set v "{name=\"$name\",in_scope=\"true\",type_changed=\"true\",new_type=\"$new_type\",new_num_children=\"$new_children\"}"
+ set v "{name=\"$name\",in_scope=\"true\",type_changed=\"true\",new_type=\"$new_type\",new_num_children=\"$new_children\",has_more=\".\"}"
set er "\\^done,changelist=\\\[$v\\\]"
verbose -log "Expecting: $er"
mi_gdb_test "-var-update $name" $er $testname
}
-# Update a dynamic varobj named NAME. CHILDREN is a list of children,
-# in the same form as mi_list_varobj_children. TESTNAME is the name
-# of the test.
-proc mi_varobj_update_dynamic {name children testname} {
- set children_exp_j [mi_child_regexp $children 0]
+# A helper that turns a key/value list into a regular expression
+# matching some MI output.
+proc mi_varobj_update_kv_helper {list} {
+ set first 1
+ set rx ""
+ foreach {key value} $list {
+ if {!$first} {
+ append rx ,
+ }
+ set first 0
+ if {$key == "new_children"} {
+ append rx "$key=\\\[$value\\\]"
+ } else {
+ append rx "$key=\"$value\""
+ }
+ }
+ return $rx
+}
- set er "\\^done,changelist=\\\["
+# A helper for mi_varobj_update_dynamic that computes a match
+# expression given a child list.
+proc mi_varobj_update_dynamic_helper {children} {
+ set crx ""
- append er "{name=\"$name\",in_scope=\"true\",type_changed=\"false\""
- append er ",children=\\\[$children_exp_j.*\\\]}\\\]"
+ set first 1
+ foreach child $children {
+ if {!$first} {
+ append crx ,
+ }
+ set first 0
+ append crx "{"
+ append crx [mi_varobj_update_kv_helper $child]
+ append crx "}"
+ }
+
+ return $crx
+}
+
+# Update a dynamic varobj named NAME. CHILDREN is a list of children
+# that have been updated; NEW_CHILDREN is a list of children that were
+# added to the primary varobj. Each child is a list of key/value
+# pairs that are expected. SELF is a key/value list holding
+# information about the varobj itself. TESTNAME is the name of the
+# test.
+proc mi_varobj_update_dynamic {name testname self children new_children} {
+ if {[llength $new_children]} {
+ set newrx [mi_varobj_update_dynamic_helper $new_children]
+ lappend self new_children $newrx
+ }
+ set selfrx [mi_varobj_update_kv_helper $self]
+ set crx [mi_varobj_update_dynamic_helper $children]
+
+ set er "\\^done,changelist=\\\[\{name=\"$name\",in_scope=\"true\""
+ append er ",$selfrx\}"
+ if {"$crx" != ""} {
+ append er ",$crx"
+ }
+ append er "\\\]"
verbose -log "Expecting: $er"
mi_gdb_test "-var-update $name" $er $testname
@@ -1329,14 +1385,13 @@ proc mi_child_regexp {children add_child} {
# have no value.
#
proc mi_list_varobj_children { varname children testname } {
- mi_list_varobj_children_range $varname [llength $children] $children \
+ mi_list_varobj_children_range $varname "" "" [llength $children] $children \
$testname
}
-# Like mi_list_varobj_children, but assumes that a subrange has been
-# selected with -var-set-child-range. NUMCHILDREN is the total number
-# of children.
-proc mi_list_varobj_children_range {varname numchildren children testname} {
+# Like mi_list_varobj_children, but sets a subrange. NUMCHILDREN is
+# the total number of children.
+proc mi_list_varobj_children_range {varname from to numchildren children testname} {
set options ""
if {[llength $varname] == 2} {
set options [lindex $varname 1]
@@ -1352,9 +1407,18 @@ proc mi_list_varobj_children_range {varname numchildren children testname} {
set expected "\\^done,numchild=\"0\""
}
+ if {"$to" == ""} {
+ append expected ",has_more=\"0\""
+ } elseif {$to >= 0 && $numchildren > $to} {
+ append expected ",has_more=\"1\""
+ } else {
+ append expected ",has_more=\"0\""
+ }
+
verbose -log "Expecting: $expected"
- mi_gdb_test "-var-list-children $options $varname" $expected $testname
+ mi_gdb_test "-var-list-children $options $varname $from $to" \
+ $expected $testname
}
# Verifies that variable object VARNAME has NUMBER children,
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 603071f..7235635 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -29,6 +29,7 @@
#include "gdb_assert.h"
#include "gdb_string.h"
+#include "gdb_regex.h"
#include "varobj.h"
#include "vec.h"
@@ -59,6 +60,15 @@ char *varobj_format_string[] =
/* String representations of gdb's known languages */
char *varobj_language_string[] = { "unknown", "C", "C++", "Java" };
+/* True if we want to allow Python-based pretty-printing. */
+static int pretty_printing = 0;
+
+void
+varobj_enable_pretty_printing (void)
+{
+ pretty_printing = 1;
+}
+
/* Data structures */
/* Every root variable has one of these structures saved in its
@@ -173,9 +183,31 @@ struct varobj
frozen. */
int not_fetched;
+ /* Sub-range of children which the MI consumer has requested. If
+ FROM < 0 or TO < 0, means that all children have been
+ requested. */
+ int from;
+ int to;
+
+ /* The pretty-printer constructor. If NULL, then the default
+ pretty-printer will be looked up. If None, then no
+ pretty-printer will be installed. */
+ PyObject *constructor;
+
/* The pretty-printer that has been constructed. If NULL, then a
new printer object is needed, and one will be constructed. */
PyObject *pretty_printer;
+
+ /* The iterator returned by the printer's 'children' method, or NULL
+ if not available. */
+ PyObject *child_iter;
+
+ /* We request one extra item from the iterator, so that we can
+ report to the caller whether there are more items than we have
+ already reported. However, we don't want to install this value
+ when we read it, because that will mess up future updates. So,
+ we stash it here instead. */
+ PyObject *saved_item;
};
struct cpstack
@@ -236,8 +268,6 @@ static char *cppop (struct cpstack **pstack);
static int install_new_value (struct varobj *var, struct value *value,
int initial);
-static void install_default_visualizer (struct varobj *var);
-
/* Language-specific routines. */
static enum varobj_languages variable_language (struct varobj *var);
@@ -623,7 +653,6 @@ varobj_create (char *objname,
}
}
- install_default_visualizer (var);
discard_cleanups (old_chain);
return var;
}
@@ -738,15 +767,8 @@ instantiate_pretty_printer (PyObject *constructor, struct value *value)
#if HAVE_PYTHON
PyObject *val_obj = NULL;
PyObject *printer;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- value = value_copy (value);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
val_obj = value_to_value_object (value);
-
if (! val_obj)
return NULL;
@@ -810,6 +832,17 @@ varobj_get_display_hint (struct varobj *var)
return result;
}
+/* Return true if the varobj has items after TO, false otherwise. */
+
+int
+varobj_has_more (struct varobj *var, int to)
+{
+ if (VEC_length (varobj_p, var->children) > to)
+ return 1;
+ return ((to == -1 || VEC_length (varobj_p, var->children) == to)
+ && var->saved_item != NULL);
+}
+
/* If the variable object is bound to a specific thread, that
is its evaluation can always be done in context of a frame
inside that thread, returns GDB id of the thread -- which
@@ -842,22 +875,97 @@ varobj_get_frozen (struct varobj *var)
return var->frozen;
}
+/* A helper function that restricts a range to what is actually
+ available in a VEC. This follows the usual rules for the meaning
+ of FROM and TO -- if either is negative, the entire range is
+ used. */
+
+static void
+restrict_range (VEC (varobj_p) *children, int *from, int *to)
+{
+ if (*from < 0 || *to < 0)
+ {
+ *from = 0;
+ *to = VEC_length (varobj_p, children);
+ }
+ else
+ {
+ if (*from > VEC_length (varobj_p, children))
+ *from = VEC_length (varobj_p, children);
+ if (*to > VEC_length (varobj_p, children))
+ *to = VEC_length (varobj_p, children);
+ if (*from > *to)
+ *from = *to;
+ }
+}
+
+/* A helper for update_dynamic_varobj_children that installs a new
+ child when needed. */
+
+static void
+install_dynamic_child (struct varobj *var,
+ VEC (varobj_p) **changed,
+ VEC (varobj_p) **new,
+ VEC (varobj_p) **unchanged,
+ int *cchanged,
+ int index,
+ const char *name,
+ struct value *value)
+{
+ if (VEC_length (varobj_p, var->children) < index + 1)
+ {
+ /* There's no child yet. */
+ struct varobj *child = varobj_add_child (var, name, value);
+ if (new)
+ {
+ VEC_safe_push (varobj_p, *new, child);
+ *cchanged = 1;
+ }
+ }
+ else
+ {
+ varobj_p existing = VEC_index (varobj_p, var->children, index);
+ if (install_new_value (existing, value, 0))
+ {
+ if (changed)
+ VEC_safe_push (varobj_p, *changed, existing);
+ }
+ else if (unchanged)
+ VEC_safe_push (varobj_p, *unchanged, existing);
+ }
+}
+
+#if HAVE_PYTHON
+
+static int
+dynamic_varobj_has_child_method (struct varobj *var)
+{
+ struct cleanup *back_to;
+ PyObject *printer = var->pretty_printer;
+ int result;
+
+ back_to = varobj_ensure_python_env (var);
+ result = PyObject_HasAttr (printer, gdbpy_children_cst);
+ do_cleanups (back_to);
+ return result;
+}
+
+#endif
+
static int
update_dynamic_varobj_children (struct varobj *var,
VEC (varobj_p) **changed,
- VEC (varobj_p) **new_and_unchanged,
- int *cchanged)
-
+ VEC (varobj_p) **new,
+ VEC (varobj_p) **unchanged,
+ int *cchanged,
+ int update_children,
+ int from,
+ int to)
{
#if HAVE_PYTHON
- /* FIXME: we *might* want to provide this functionality as
- a standalone function, so that other interested parties
- than varobj code can benefit for this. */
struct cleanup *back_to;
PyObject *children;
- PyObject *iterator;
int i;
- int children_changed = 0;
PyObject *printer = var->pretty_printer;
back_to = varobj_ensure_python_env (var);
@@ -869,87 +977,106 @@ update_dynamic_varobj_children (struct varobj *var,
return 0;
}
- children = PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
- NULL);
-
- if (!children)
+ if (update_children || !var->child_iter)
{
- gdbpy_print_stack ();
- error (_("Null value returned for children"));
- }
+ children = PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
+ NULL);
- make_cleanup_py_decref (children);
+ if (!children)
+ {
+ gdbpy_print_stack ();
+ error (_("Null value returned for children"));
+ }
- if (!PyIter_Check (children))
- error (_("Returned value is not iterable"));
+ make_cleanup_py_decref (children);
- iterator = PyObject_GetIter (children);
- if (!iterator)
- {
- gdbpy_print_stack ();
- error (_("Could not get children iterator"));
+ if (!PyIter_Check (children))
+ error (_("Returned value is not iterable"));
+
+ Py_XDECREF (var->child_iter);
+ var->child_iter = PyObject_GetIter (children);
+ if (!var->child_iter)
+ {
+ gdbpy_print_stack ();
+ error (_("Could not get children iterator"));
+ }
+
+ Py_XDECREF (var->saved_item);
+ var->saved_item = NULL;
+
+ i = 0;
}
- make_cleanup_py_decref (iterator);
+ else
+ i = VEC_length (varobj_p, var->children);
- for (i = 0; ; ++i)
+ /* We ask for one extra child, so that MI can report whether there
+ are more children. */
+ for (; to < 0 || i < to + 1; ++i)
{
- PyObject *item = PyIter_Next (iterator);
- PyObject *py_v;
- struct value *v;
- char *name;
- struct cleanup *inner;
-
- if (!item)
- break;
- inner = make_cleanup_py_decref (item);
+ PyObject *item;
- if (!PyArg_ParseTuple (item, "sO", &name, &py_v))
- error (_("Invalid item from the child list"));
-
- v = convert_value_from_python (py_v);
+ /* See if there was a leftover from last time. */
+ if (var->saved_item)
+ {
+ item = var->saved_item;
+ var->saved_item = NULL;
+ }
+ else
+ item = PyIter_Next (var->child_iter);
- /* TODO: This assume the name of the i-th child never changes. */
+ if (!item)
+ break;
- /* Now see what to do here. */
- if (VEC_length (varobj_p, var->children) < i + 1)
+ /* We don't want to push the extra child on any report list. */
+ if (to < 0 || i < to)
{
- /* There's no child yet. */
- struct varobj *child = varobj_add_child (var, name, v);
- if (new_and_unchanged)
- VEC_safe_push (varobj_p, *new_and_unchanged, child);
- children_changed = 1;
+ PyObject *py_v;
+ char *name;
+ struct value *v;
+ struct cleanup *inner;
+ int can_mention = from < 0 || i >= from;
+
+ inner = make_cleanup_py_decref (item);
+
+ if (!PyArg_ParseTuple (item, "sO", &name, &py_v))
+ error (_("Invalid item from the child list"));
+
+ v = convert_value_from_python (py_v);
+ install_dynamic_child (var, can_mention ? changed : NULL,
+ can_mention ? new : NULL,
+ can_mention ? unchanged : NULL,
+ can_mention ? cchanged : NULL, i, name, v);
+ do_cleanups (inner);
}
- else
+ else
{
- varobj_p existing = VEC_index (varobj_p, var->children, i);
- if (install_new_value (existing, v, 0) && changed)
- {
- if (changed)
- VEC_safe_push (varobj_p, *changed, existing);
- }
- else
- {
- if (new_and_unchanged)
- VEC_safe_push (varobj_p, *new_and_unchanged, existing);
- }
- }
+ Py_XDECREF (var->saved_item);
+ var->saved_item = item;
- do_cleanups (inner);
+ /* We want to truncate the child list just before this
+ element. */
+ break;
+ }
}
if (i < VEC_length (varobj_p, var->children))
{
- int i;
- children_changed = 1;
- for (i = 0; i < VEC_length (varobj_p, var->children); ++i)
- varobj_delete (VEC_index (varobj_p, var->children, i), NULL, 0);
+ int j;
+ *cchanged = 1;
+ for (j = i; j < VEC_length (varobj_p, var->children); ++j)
+ varobj_delete (VEC_index (varobj_p, var->children, j), NULL, 0);
+ VEC_truncate (varobj_p, var->children, i);
}
- VEC_truncate (varobj_p, var->children, i);
+
+ /* If there are fewer children than requested, note that the list of
+ children changed. */
+ if (to >= 0 && VEC_length (varobj_p, var->children) < to)
+ *cchanged = 1;
+
var->num_children = VEC_length (varobj_p, var->children);
do_cleanups (back_to);
- *cchanged = children_changed;
return 1;
#else
gdb_assert (0 && "should never be called if Python is not enabled");
@@ -961,20 +1088,27 @@ varobj_get_num_children (struct varobj *var)
{
if (var->num_children == -1)
{
- int changed;
- if (!var->pretty_printer
- || !update_dynamic_varobj_children (var, NULL, NULL, &changed))
+ if (var->pretty_printer)
+ {
+ int dummy;
+
+ /* If we have a dynamic varobj, don't report -1 children.
+ So, try to fetch some children first. */
+ update_dynamic_varobj_children (var, NULL, NULL, NULL, &dummy,
+ 0, 0, 0);
+ }
+ else
var->num_children = number_of_children (var);
}
- return var->num_children;
+ return var->num_children >= 0 ? var->num_children : 0;
}
/* Creates a list of the immediate children of a variable object;
the return code is the number of such children or -1 on error */
VEC (varobj_p)*
-varobj_list_children (struct varobj *var)
+varobj_list_children (struct varobj *var, int *from, int *to)
{
struct varobj *child;
char *name;
@@ -982,12 +1116,16 @@ varobj_list_children (struct varobj *var)
var->children_requested = 1;
- if (var->pretty_printer
+ if (var->pretty_printer)
+ {
/* This, in theory, can result in the number of children changing without
frontend noticing. But well, calling -var-list-children on the same
varobj twice is not something a sane frontend would do. */
- && update_dynamic_varobj_children (var, NULL, NULL, &children_changed))
- return var->children;
+ update_dynamic_varobj_children (var, NULL, NULL, NULL, &children_changed,
+ 0, 0, *to);
+ restrict_range (var->children, from, to);
+ return var->children;
+ }
if (var->num_children == -1)
var->num_children = number_of_children (var);
@@ -1013,10 +1151,10 @@ varobj_list_children (struct varobj *var)
name = name_of_child (var, i);
existing = create_child (var, i, name);
VEC_replace (varobj_p, var->children, i, existing);
- install_default_visualizer (existing);
}
}
+ restrict_range (var->children, from, to);
return var->children;
}
@@ -1027,7 +1165,6 @@ varobj_add_child (struct varobj *var, const char *name, struct value *value)
VEC_length (varobj_p, var->children),
name, value);
VEC_safe_push (varobj_p, var->children, v);
- install_default_visualizer (v);
return v;
}
@@ -1089,6 +1226,12 @@ varobj_get_attributes (struct varobj *var)
return attributes;
}
+int
+varobj_pretty_printed_p (struct varobj *var)
+{
+ return var->pretty_printer != NULL;
+}
+
char *
varobj_get_formatted_value (struct varobj *var,
enum varobj_display_formats format)
@@ -1166,6 +1309,116 @@ varobj_set_value (struct varobj *var, char *expression)
return 1;
}
+#if HAVE_PYTHON
+
+/* A helper function to install a constructor function and visualizer
+ in a varobj. */
+
+static void
+install_visualizer (struct varobj *var, PyObject *constructor,
+ PyObject *visualizer)
+{
+ Py_XDECREF (var->constructor);
+ var->constructor = constructor;
+
+ Py_XDECREF (var->pretty_printer);
+ var->pretty_printer = visualizer;
+
+ Py_XDECREF (var->child_iter);
+ var->child_iter = NULL;
+}
+
+/* Install the default visualizer for VAR. */
+
+static void
+install_default_visualizer (struct varobj *var)
+{
+ if (pretty_printing)
+ {
+ PyObject *pretty_printer = NULL;
+
+ if (var->value)
+ {
+ pretty_printer = gdbpy_get_varobj_pretty_printer (var->value);
+ if (! pretty_printer)
+ {
+ gdbpy_print_stack ();
+ error (_("Cannot instantiate printer for default visualizer"));
+ }
+ }
+
+ if (pretty_printer == Py_None)
+ {
+ Py_DECREF (pretty_printer);
+ pretty_printer = NULL;
+ }
+
+ install_visualizer (var, NULL, pretty_printer);
+ }
+}
+
+/* Instantiate and install a visualizer for VAR using CONSTRUCTOR to
+ make a new object. */
+
+static void
+construct_visualizer (struct varobj *var, PyObject *constructor)
+{
+ PyObject *pretty_printer;
+
+ Py_INCREF (constructor);
+ if (constructor == Py_None)
+ pretty_printer = NULL;
+ else
+ {
+ pretty_printer = instantiate_pretty_printer (constructor, var->value);
+ if (! pretty_printer)
+ {
+ gdbpy_print_stack ();
+ Py_DECREF (constructor);
+ constructor = Py_None;
+ Py_INCREF (constructor);
+ }
+
+ if (pretty_printer == Py_None)
+ {
+ Py_DECREF (pretty_printer);
+ pretty_printer = NULL;
+ }
+ }
+
+ install_visualizer (var, constructor, pretty_printer);
+}
+
+#endif /* HAVE_PYTHON */
+
+/* A helper function for install_new_value. This creates and installs
+ a visualizer for VAR, if appropriate. */
+
+static void
+install_new_value_visualizer (struct varobj *var)
+{
+#if HAVE_PYTHON
+ /* If the constructor is None, then we want the raw value. If VAR
+ does not have a value, just skip this. */
+ if (var->constructor != Py_None && var->value)
+ {
+ struct cleanup *cleanup;
+ PyObject *pretty_printer = NULL;
+
+ cleanup = varobj_ensure_python_env (var);
+
+ if (!var->constructor)
+ install_default_visualizer (var);
+ else
+ construct_visualizer (var, var->constructor);
+
+ do_cleanups (cleanup);
+ }
+#else
+ /* Do nothing. */
+#endif
+}
+
/* Assign a new value to a variable object. If INITIAL is non-zero,
this is the first assignement after the variable object was just
created, or changed type. In that case, just assign the value
@@ -1206,10 +1459,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
that in C++ a reference is not rebindable, it cannot
meaningfully change. So, get hold of the real value. */
if (value)
- {
- value = coerce_ref (value);
- release_value (value);
- }
+ value = coerce_ref (value);
if (var->type && TYPE_CODE (var->type) == TYPE_CODE_UNION)
/* For unions, we need to fetch the value implicitly because
@@ -1256,7 +1506,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
values. Don't get string rendering if the value is
lazy -- if it is, the code above has decided that the value
should not be fetched. */
- if (value && !value_lazy (value))
+ if (value && !value_lazy (value) && !var->pretty_printer)
print_value = value_get_print_value (value, var->format, var);
/* If the type is changeable, compare the old and the new values.
@@ -1272,7 +1522,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
{
changed = 1;
}
- else
+ else if (! var->pretty_printer)
{
/* Try to compare the values. That requires that both
values are non-lazy. */
@@ -1317,74 +1567,53 @@ install_new_value (struct varobj *var, struct value *value, int initial)
if (var->value != NULL && var->value != value)
value_free (var->value);
var->value = value;
- if (var->print_value)
- xfree (var->print_value);
- var->print_value = print_value;
+ if (value != NULL)
+ value_incref (value);
if (value && value_lazy (value) && intentionally_not_fetched)
var->not_fetched = 1;
else
var->not_fetched = 0;
var->updated = 0;
+ install_new_value_visualizer (var);
+
+ /* If we installed a pretty-printer, re-compare the printed version
+ to see if the variable changed. */
+ if (var->pretty_printer)
+ {
+ xfree (print_value);
+ print_value = value_get_print_value (var->value, var->format, var);
+ if (!var->print_value || strcmp (var->print_value, print_value) != 0)
+ changed = 1;
+ }
+ if (var->print_value)
+ xfree (var->print_value);
+ var->print_value = print_value;
+
gdb_assert (!var->value || value_type (var->value));
return changed;
}
-static void
-install_visualizer (struct varobj *var, PyObject *visualizer)
+/* Return the requested range for a varobj. VAR is the varobj. FROM
+ and TO are out parameters; *FROM and *TO will be set to the
+ selected sub-range of VAR. If no range was selected using
+ -var-set-update-range, then both will be -1. */
+void
+varobj_get_child_range (struct varobj *var, int *from, int *to)
{
-#if HAVE_PYTHON
- /* If there are any children now, wipe them. */
- varobj_delete (var, NULL, 1 /* children only */);
- var->num_children = -1;
-
- Py_XDECREF (var->pretty_printer);
- var->pretty_printer = visualizer;
-
- install_new_value (var, var->value, 1);
-
- /* If we removed the visualizer, and the user ever requested the
- object's children, then we must compute the list of children.
- Note that we needn't do this when installing a visualizer,
- because updating will recompute dynamic children. */
- if (!visualizer && var->children_requested)
- varobj_list_children (var);
-#else
- error (_("Python support required"));
-#endif
+ *from = var->from;
+ *to = var->to;
}
-static void
-install_default_visualizer (struct varobj *var)
+/* Set the selected sub-range of children of VAR to start at index
+ FROM and end at index TO. If either FROM or TO is less than zero,
+ this is interpreted as a request for all children. */
+void
+varobj_set_child_range (struct varobj *var, int from, int to)
{
-#if HAVE_PYTHON
- struct cleanup *cleanup;
- PyObject *pretty_printer = NULL;
-
- cleanup = varobj_ensure_python_env (var);
-
- if (var->value)
- {
- pretty_printer = gdbpy_get_varobj_pretty_printer (var->value);
- if (! pretty_printer)
- {
- gdbpy_print_stack ();
- error (_("Cannot instantiate printer for default visualizer"));
- }
- }
-
- if (pretty_printer == Py_None)
- {
- Py_DECREF (pretty_printer);
- pretty_printer = NULL;
- }
-
- install_visualizer (var, pretty_printer);
- do_cleanups (cleanup);
-#else
- /* No error is right as this function is inserted just as a hook. */
-#endif
+ var->from = from;
+ var->to = to;
}
void
@@ -1402,31 +1631,19 @@ varobj_set_visualizer (struct varobj *var, const char *visualizer)
make_cleanup_py_decref (globals);
constructor = PyRun_String (visualizer, Py_eval_input, globals, globals);
-
- /* Do not instantiate NoneType. */
- if (constructor == Py_None)
- {
- pretty_printer = Py_None;
- Py_INCREF (pretty_printer);
- }
- else
- pretty_printer = instantiate_pretty_printer (constructor, var->value);
-
- Py_XDECREF (constructor);
- if (! pretty_printer)
+ if (! constructor)
{
gdbpy_print_stack ();
error (_("Could not evaluate visualizer expression: %s"), visualizer);
}
- if (pretty_printer == Py_None)
- {
- Py_DECREF (pretty_printer);
- pretty_printer = NULL;
- }
+ construct_visualizer (var, constructor);
+ Py_XDECREF (constructor);
- install_visualizer (var, pretty_printer);
+ /* If there are any children now, wipe them. */
+ varobj_delete (var, NULL, 1 /* children only */);
+ var->num_children = -1;
do_cleanups (back_to);
#else
@@ -1537,44 +1754,80 @@ VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit)
/* We probably should not get children of a varobj that has a
pretty-printer, but for which -var-list-children was never
- invoked. Presumably, such varobj is not yet expanded in the
- UI, so we need not bother getting it. */
+ invoked. */
if (v->pretty_printer)
{
- VEC (varobj_p) *changed = 0, *new_and_unchanged = 0;
+ VEC (varobj_p) *changed = 0, *new = 0, *unchanged = 0;
int i, children_changed;
- varobj_p tmp;
-
- if (!v->children_requested)
- continue;
if (v->frozen)
continue;
+ if (!v->children_requested)
+ {
+ int dummy;
+
+ /* If we initially did not have potential children, but
+ now we do, consider the varobj as changed.
+ Otherwise, if children were never requested, consider
+ it as unchanged -- presumably, such varobj is not yet
+ expanded in the UI, so we need not bother getting
+ it. */
+ if (!varobj_has_more (v, 0))
+ {
+ update_dynamic_varobj_children (v, NULL, NULL, NULL,
+ &dummy, 0, 0, 0);
+ if (varobj_has_more (v, 0))
+ r.changed = 1;
+ }
+
+ if (r.changed)
+ VEC_safe_push (varobj_update_result, result, &r);
+
+ continue;
+ }
+
/* If update_dynamic_varobj_children returns 0, then we have
a non-conforming pretty-printer, so we skip it. */
- if (update_dynamic_varobj_children (v, &changed, &new_and_unchanged,
- &children_changed))
+ if (update_dynamic_varobj_children (v, &changed, &new, &unchanged,
+ &children_changed, 1,
+ v->from, v->to))
{
- if (children_changed)
- r.children_changed = 1;
- for (i = 0; VEC_iterate (varobj_p, changed, i, tmp); ++i)
+ if (children_changed || new)
{
- varobj_update_result r = {tmp};
- r.changed = 1;
- r.value_installed = 1;
- VEC_safe_push (varobj_update_result, stack, &r);
+ r.children_changed = 1;
+ r.new = new;
}
- for (i = 0;
- VEC_iterate (varobj_p, new_and_unchanged, i, tmp);
- ++i)
+ /* Push in reverse order so that the first child is
+ popped from the work stack first, and so will be
+ added to result first. This does not affect
+ correctness, just "nicer". */
+ for (i = VEC_length (varobj_p, changed) - 1; i >= 0; --i)
{
+ varobj_p tmp = VEC_index (varobj_p, changed, i);
varobj_update_result r = {tmp};
+ r.changed = 1;
r.value_installed = 1;
VEC_safe_push (varobj_update_result, stack, &r);
}
+ for (i = VEC_length (varobj_p, unchanged) - 1; i >= 0; --i)
+ {
+ varobj_p tmp = VEC_index (varobj_p, unchanged, i);
+ if (!tmp->frozen)
+ {
+ varobj_update_result r = {tmp};
+ r.value_installed = 1;
+ VEC_safe_push (varobj_update_result, stack, &r);
+ }
+ }
if (r.changed || r.children_changed)
VEC_safe_push (varobj_update_result, result, &r);
+
+ /* Free CHANGED and UNCHANGED, but not NEW, because NEW
+ has been put into the result vector. */
+ VEC_free (varobj_p, changed);
+ VEC_free (varobj_p, unchanged);
+
continue;
}
}
@@ -1862,7 +2115,12 @@ new_variable (void)
var->frozen = 0;
var->not_fetched = 0;
var->children_requested = 0;
+ var->from = -1;
+ var->to = -1;
+ var->constructor = 0;
var->pretty_printer = 0;
+ var->child_iter = 0;
+ var->saved_item = 0;
return var;
}
@@ -1892,7 +2150,10 @@ free_variable (struct varobj *var)
if (var->pretty_printer)
{
struct cleanup *cleanup = varobj_ensure_python_env (var);
- Py_DECREF (var->pretty_printer);
+ Py_XDECREF (var->constructor);
+ Py_XDECREF (var->pretty_printer);
+ Py_XDECREF (var->child_iter);
+ Py_XDECREF (var->saved_item);
do_cleanups (cleanup);
}
#endif
@@ -2139,6 +2400,8 @@ value_of_root (struct varobj **var_handle, int *type_changed)
else
{
tmp_var->obj_name = xstrdup (var->obj_name);
+ tmp_var->from = var->from;
+ tmp_var->to = var->to;
varobj_delete (var, NULL, 0);
install_variable (tmp_var);
@@ -2173,7 +2436,11 @@ static char *
my_value_of_variable (struct varobj *var, enum varobj_display_formats format)
{
if (var->root->is_valid)
- return (*var->root->lang->value_of_variable) (var, format);
+ {
+ if (var->pretty_printer)
+ return value_get_print_value (var->value, var->format, var);
+ return (*var->root->lang->value_of_variable) (var, format);
+ }
else
return NULL;
}
@@ -2196,43 +2463,51 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
struct cleanup *back_to = varobj_ensure_python_env (var);
PyObject *value_formatter = var->pretty_printer;
- if (value_formatter && PyObject_HasAttr (value_formatter,
- gdbpy_to_string_cst))
+ if (value_formatter)
{
- char *hint;
- struct value *replacement;
- int string_print = 0;
- PyObject *output = NULL;
+ /* First check to see if we have any children at all. If so,
+ we simply return {...}. */
+ if (dynamic_varobj_has_child_method (var))
+ return xstrdup ("{...}");
- hint = gdbpy_get_display_hint (value_formatter);
- if (hint)
+ if (PyObject_HasAttr (value_formatter, gdbpy_to_string_cst))
{
- if (!strcmp (hint, "string"))
- string_print = 1;
- xfree (hint);
- }
+ char *hint;
+ struct value *replacement;
+ int string_print = 0;
+ PyObject *output = NULL;
+
+ hint = gdbpy_get_display_hint (value_formatter);
+ if (hint)
+ {
+ if (!strcmp (hint, "string"))
+ string_print = 1;
+ xfree (hint);
+ }
- output = apply_varobj_pretty_printer (value_formatter,
- &replacement);
- if (output)
- {
- PyObject *py_str = python_string_to_target_python_string (output);
- if (py_str)
- {
- char *s = PyString_AsString (py_str);
- len = PyString_Size (py_str);
- thevalue = xmemdup (s, len + 1, len + 1);
- Py_DECREF (py_str);
+ output = apply_varobj_pretty_printer (value_formatter,
+ &replacement);
+ if (output)
+ {
+ PyObject *py_str
+ = python_string_to_target_python_string (output);
+ if (py_str)
+ {
+ char *s = PyString_AsString (py_str);
+ len = PyString_Size (py_str);
+ thevalue = xmemdup (s, len + 1, len + 1);
+ Py_DECREF (py_str);
+ }
+ Py_DECREF (output);
}
- Py_DECREF (output);
- }
- if (thevalue && !string_print)
- {
- do_cleanups (back_to);
- return thevalue;
+ if (thevalue && !string_print)
+ {
+ do_cleanups (back_to);
+ return thevalue;
+ }
+ if (replacement)
+ value = replacement;
}
- if (replacement)
- value = replacement;
}
do_cleanups (back_to);
}
@@ -2961,10 +3236,7 @@ cplus_describe_child (struct varobj *parent, int index,
*cname = xstrdup (TYPE_FIELD_NAME (type, index));
if (cvalue && value)
- {
- *cvalue = value_cast (TYPE_FIELD_TYPE (type, index), value);
- release_value (*cvalue);
- }
+ *cvalue = value_cast (TYPE_FIELD_TYPE (type, index), value);
if (ctype)
{
diff --git a/gdb/varobj.h b/gdb/varobj.h
index 7297243..f43c593 100644
--- a/gdb/varobj.h
+++ b/gdb/varobj.h
@@ -78,6 +78,12 @@ typedef struct varobj_update_result_t
new value of varobj is already computed and installed, or has to
be yet installed. Don't use this outside varobj.c */
int value_installed;
+
+ /* This will be non-NULL when new children were added to the varobj.
+ It lists the new children (which must necessarily come at the end
+ of the child list) added during an update. The caller is
+ responsible for freeing this vector. */
+ VEC (varobj_p) *new;
} varobj_update_result;
DEF_VEC_O (varobj_update_result);
@@ -112,13 +118,24 @@ extern void varobj_set_frozen (struct varobj *var, int frozen);
extern int varobj_get_frozen (struct varobj *var);
+extern void varobj_get_child_range (struct varobj *var, int *from, int *to);
+
+extern void varobj_set_child_range (struct varobj *var, int from, int to);
+
extern char *varobj_get_display_hint (struct varobj *var);
extern int varobj_get_num_children (struct varobj *var);
-/* Return the list of children of VAR. The returned vector
- should not be modified in any way. */
-extern VEC (varobj_p)* varobj_list_children (struct varobj *var);
+/* Return the list of children of VAR. The returned vector should not
+ be modified in any way. FROM and TO are in/out parameters
+ indicating the range of children to return. If either *FROM or *TO
+ is less than zero on entry, then all children will be returned. On
+ return, *FROM and *TO will be updated to indicate the real range
+ that was returned. The resulting VEC will contain at least the
+ children from *FROM to just before *TO; it might contain more
+ children, depending on whether any more were available. */
+extern VEC (varobj_p)* varobj_list_children (struct varobj *var,
+ int *from, int *to);
extern char *varobj_get_type (struct varobj *var);
@@ -149,6 +166,13 @@ extern int varobj_editable_p (struct varobj *var);
extern int varobj_floating_p (struct varobj *var);
-extern void varobj_set_visualizer (struct varobj *var, const char *visualizer);
+extern void
+varobj_set_visualizer (struct varobj *var, const char *visualizer);
+
+extern void varobj_enable_pretty_printing (void);
+
+extern int varobj_has_more (struct varobj *var, int to);
+
+extern int varobj_pretty_printed_p (struct varobj *var);
#endif /* VAROBJ_H */
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-10 20:58 Patch: implement new dynamic varobj spec Tom Tromey
` (3 preceding siblings ...)
2009-09-14 20:05 ` Tom Tromey
@ 2009-09-18 9:29 ` Vladimir Prus
2009-09-18 18:25 ` Tom Tromey
2009-09-19 12:57 ` Vladimir Prus
4 siblings, 2 replies; 39+ messages in thread
From: Vladimir Prus @ 2009-09-18 9:29 UTC (permalink / raw)
To: gdb-patches
Tom Tromey wrote:
> This is the long-awaited dynamic varobj patch.
> It implements the spec as described by Vladimir:
>
> http://sourceware.org/ml/gdb/2009-07/msg00088.html
>
> .. with various minor changes we've discussed on that thread and
> elsewhere. I didn't give the follow-up URLs; I think that the doc patch
> ought to be sufficient, and if it isn't, I will fix it up.
>
> This has been in development for quite a while, including testing using
> two different MI consumers (Vladimir's and one by Noam Yorav-Raphael).
>
> There are three outstanding bugs.
>
> * A dynamic varobj bug that I couldn't reproduce
> http://sourceware.org/ml/archer/2009-q3/msg00169.html
I've got with gdb-inside-gdb. What happens is:
- we have uninitialized std::vector<std::string> (did I already say that gcc produces
bogus debug info?)
- The 'strings' at the address where supposed storage of the bogus vector is
point nowhere.
- When Python code tries to pretty-print inaccassible memory, it gives:
Traceback (most recent call last):
File "/home/ghost/Build/python/libstdcxx/v6/printers.py", line 469, in to_string
return self.val['_M_dataplus']['_M_p'].string (encoding, length = len)
RuntimeError: Cannot access memory at address 0xcf
- Inside GDB, pretty_print_one_value catches the above exception, and returns 0.
- The rest of GDB fallbacks to printing the value as it would without Python
pretty-printing. And with 'set print pretty 1', it pretty-prints the raw value.
I think there are two things worth fixing:
1. set print pretty 1 should have no effect on MI. I can handle this part.
2. pretty-printer for string should catch exception and return "<inaccessible>"
or some such. Alternatively, GDB should not fallback to regular display if
Python pretty-printer fails. Yet alternatively, GDB should distinguish between
different failure modes of Python pretty-printer, since memory access error
likely to be caused by uninitalized data and should not cause fallback.
Does this make any sense?
- Volodya
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: RFA: mark -enable-pretty-printing as experimental (Was: Patch: implement new dynamic varobj spec)
[not found] ` <h8vk80$fqc$2@ger.gmane.org>
@ 2009-09-18 10:02 ` Eli Zaretskii
2009-09-18 18:01 ` RFA: mark -enable-pretty-printing as experimental Tom Tromey
0 siblings, 1 reply; 39+ messages in thread
From: Eli Zaretskii @ 2009-09-18 10:02 UTC (permalink / raw)
To: Vladimir Prus; +Cc: gdb-patches
> From: Vladimir Prus <vladimir@codesourcery.com>
> Date: Fri, 18 Sep 2009 13:35:00 +0400
>
> > + This feature is currently experimental, and may work differently in
> > + future versions of @value{GDBN}.
> > +
> > @subheading The @code{-var-create} Command
> > @findex -var-create
>
> This looks fine to me. Eli?
I already replied yesterday, but somehow my mail doesn't show in the
list archives, and neither you nor Tom seem to have received it.
Strange. Here it is again, from my SENT-MAIL archive:
> From: Tom Tromey <tromey@redhat.com>
> Cc: gdb-patches@redhat.com
> Date: Wed, 16 Sep 2009 13:03:25 -0600
>
> + This feature is currently experimental, and may work differently in
> + future versions of @value{GDBN}.
I suggest to qualify this by telling when is ``currently''. Something
like "(as of GDB 7.0)" would do.
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: RFA: mark -enable-pretty-printing as experimental
2009-09-18 10:02 ` Eli Zaretskii
@ 2009-09-18 18:01 ` Tom Tromey
0 siblings, 0 replies; 39+ messages in thread
From: Tom Tromey @ 2009-09-18 18:01 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: Vladimir Prus, gdb-patches
>>>>> "Eli" == Eli Zaretskii <eliz@gnu.org> writes:
Eli> I already replied yesterday, but somehow my mail doesn't show in the
Eli> list archives, and neither you nor Tom seem to have received it.
Eli> Strange. Here it is again, from my SENT-MAIL archive:
I got it.
It was misaddressed to gdb-patches@redhat.com (no "sources").
>> From: Tom Tromey <tromey@redhat.com>
>> Cc: gdb-patches@redhat.com
>> Date: Wed, 16 Sep 2009 13:03:25 -0600
>>
>> + This feature is currently experimental, and may work differently in
>> + future versions of @value{GDBN}.
Eli> I suggest to qualify this by telling when is ``currently''. Something
Eli> like "(as of GDB 7.0)" would do.
Here is what I am committing.
Tom
2009-09-18 Tom Tromey <tromey@redhat.com>
* gdb.texinfo (GDB/MI Variable Objects): -enable-pretty-printing
is experimental.
Index: gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.625
diff -u -c -r1.625 gdb.texinfo
*** gdb.texinfo 17 Sep 2009 17:49:46 -0000 1.625
--- gdb.texinfo 18 Sep 2009 17:57:55 -0000
***************
*** 23549,23554 ****
--- 23549,23557 ----
Note that if Python support has not been compiled into @value{GDBN},
this command will still succeed (and do nothing).
+ This feature is currently (as of @value{GDBN} 7.0) experimental, and
+ may work differently in future versions of @value{GDBN}.
+
@subheading The @code{-var-create} Command
@findex -var-create
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-18 9:29 ` Vladimir Prus
@ 2009-09-18 18:25 ` Tom Tromey
2009-09-19 12:57 ` Vladimir Prus
1 sibling, 0 replies; 39+ messages in thread
From: Tom Tromey @ 2009-09-18 18:25 UTC (permalink / raw)
To: Vladimir Prus; +Cc: gdb-patches
>>>>> "Volodya" == Vladimir Prus <vladimir@codesourcery.com> writes:
Volodya> 2. pretty-printer for string should catch exception and return
Volodya> "<inaccessible>" or some such. Alternatively, GDB should not
Volodya> fallback to regular display if Python pretty-printer fails. Yet
Volodya> alternatively, GDB should distinguish between different failure
Volodya> modes of Python pretty-printer, since memory access error
Volodya> likely to be caused by uninitalized data and should not cause
Volodya> fallback.
Volodya> Does this make any sense?
Yes. Of these options I lean more toward the last one.
However, I haven't thought carefully about it all yet.
Tom
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-16 23:53 ` Tom Tromey
2009-09-16 5:46 ` Vladimir Prus
@ 2009-09-19 12:01 ` Matt Rice
2009-09-19 15:59 ` Joel Brobecker
1 sibling, 1 reply; 39+ messages in thread
From: Matt Rice @ 2009-09-19 12:01 UTC (permalink / raw)
To: tromey; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 471 bytes --]
On Tue, Sep 15, 2009 at 11:48 AM, Tom Tromey <tromey@redhat.com> wrote:
> Thanks. I am checking in the appended.
gcc 4.5 gets ‘children_changed’ may be used uninitialized in this function,
even though update_dynamic_varobj_children sets it unconditionally,
seems conservative not to rely on the other function to initialize it
through the pointer passed.
09-19-2009 Matt Rice <ratmice@gmail.com>
* varobj.c (varobj_update): Initialize children_changed.
[-- Attachment #2: foo.diff --]
[-- Type: application/octet-stream, Size: 401 bytes --]
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 7235635..8f22156 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -1758,7 +1758,7 @@ VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit)
if (v->pretty_printer)
{
VEC (varobj_p) *changed = 0, *new = 0, *unchanged = 0;
- int i, children_changed;
+ int i, children_changed = 0;
if (v->frozen)
continue;
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-18 9:29 ` Vladimir Prus
2009-09-18 18:25 ` Tom Tromey
@ 2009-09-19 12:57 ` Vladimir Prus
1 sibling, 0 replies; 39+ messages in thread
From: Vladimir Prus @ 2009-09-19 12:57 UTC (permalink / raw)
To: gdb-patches
Vladimir Prus wrote:
> Tom Tromey wrote:
>
>> This is the long-awaited dynamic varobj patch.
>> It implements the spec as described by Vladimir:
>>
>> http://sourceware.org/ml/gdb/2009-07/msg00088.html
>>
>> .. with various minor changes we've discussed on that thread and
>> elsewhere. I didn't give the follow-up URLs; I think that the doc patch
>> ought to be sufficient, and if it isn't, I will fix it up.
>>
>> This has been in development for quite a while, including testing using
>> two different MI consumers (Vladimir's and one by Noam Yorav-Raphael).
>>
>> There are three outstanding bugs.
>>
>> * A dynamic varobj bug that I couldn't reproduce
>> http://sourceware.org/ml/archer/2009-q3/msg00169.html
>
> I've got with gdb-inside-gdb. What happens is:
>
> - we have uninitialized std::vector<std::string> (did I already say that gcc produces
> bogus debug info?)
> - The 'strings' at the address where supposed storage of the bogus vector is
> point nowhere.
> - When Python code tries to pretty-print inaccassible memory, it gives:
>
> Traceback (most recent call last):
> File "/home/ghost/Build/python/libstdcxx/v6/printers.py", line 469, in to_string
> return self.val['_M_dataplus']['_M_p'].string (encoding, length = len)
> RuntimeError: Cannot access memory at address 0xcf
>
> - Inside GDB, pretty_print_one_value catches the above exception, and returns 0.
> - The rest of GDB fallbacks to printing the value as it would without Python
> pretty-printing. And with 'set print pretty 1', it pretty-prints the raw value.
>
> I think there are two things worth fixing:
>
> 1. set print pretty 1 should have no effect on MI. I can handle this part.
In fact, this is wrong idea. Normally, for structures we display {...} as immediate
value, set 'set print pretty 1' does not matter. The issue here is that when
pretty-printer fails, instead of falling back to standard MI behaviour -- display
of {...} as value and structure members as children -- we fall up with printing
the value and displaying it.
I guess this something that should be fixed independently of whether we special-case
some kinds of exceptions.
- Volodya
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Patch: implement new dynamic varobj spec
2009-09-19 12:01 ` Matt Rice
@ 2009-09-19 15:59 ` Joel Brobecker
0 siblings, 0 replies; 39+ messages in thread
From: Joel Brobecker @ 2009-09-19 15:59 UTC (permalink / raw)
To: Matt Rice; +Cc: tromey, gdb-patches
> 09-19-2009 Matt Rice <ratmice@gmail.com>
>
> * varobj.c (varobj_update): Initialize children_changed.
This looks fine. We can accept this change as a tiny change while
we wait for the paperwork to complete. I will commit this in head
and branch.
--
Joel
^ permalink raw reply [flat|nested] 39+ messages in thread
end of thread, other threads:[~2009-09-19 15:59 UTC | newest]
Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-10 20:58 Patch: implement new dynamic varobj spec Tom Tromey
2009-09-11 5:41 ` Nick Roberts
2009-09-11 19:41 ` Tom Tromey
2009-09-11 20:49 ` Eli Zaretskii
2009-09-11 21:12 ` Tom Tromey
2009-09-12 8:08 ` Eli Zaretskii
2009-09-11 23:55 ` Nick Roberts
2009-09-14 19:59 ` Tom Tromey
2009-09-14 22:55 ` Nick Roberts
2009-09-15 15:37 ` Tom Tromey
2009-09-15 22:28 ` Nick Roberts
2009-09-16 5:45 ` Vladimir Prus
2009-09-16 9:56 ` Nick Roberts
2009-09-16 17:12 ` Tom Tromey
2009-09-16 22:26 ` Nick Roberts
2009-09-15 22:43 ` Nick Roberts
2009-09-16 5:39 ` Vladimir Prus
2009-09-16 9:36 ` Nick Roberts
2009-09-16 5:44 ` Vladimir Prus
2009-09-16 23:52 ` RFA: mark -enable-pretty-printing as experimental (Was: Patch: implement new dynamic varobj spec) Tom Tromey
[not found] ` <h8vk80$fqc$2@ger.gmane.org>
2009-09-18 10:02 ` Eli Zaretskii
2009-09-18 18:01 ` RFA: mark -enable-pretty-printing as experimental Tom Tromey
2009-09-14 19:56 ` Patch: implement new dynamic varobj spec Tom Tromey
2009-09-12 9:18 ` Eli Zaretskii
2009-09-14 20:03 ` Tom Tromey
2009-09-14 20:22 ` Eli Zaretskii
2009-09-14 21:29 ` Tom Tromey
2009-09-15 3:06 ` Eli Zaretskii
2009-09-14 11:24 ` Vladimir Prus
2009-09-16 23:53 ` Tom Tromey
2009-09-16 5:46 ` Vladimir Prus
2009-09-19 12:01 ` Matt Rice
2009-09-19 15:59 ` Joel Brobecker
2009-09-14 20:05 ` Tom Tromey
2009-09-14 20:24 ` Eli Zaretskii
2009-09-14 23:58 ` Nick Roberts
2009-09-18 9:29 ` Vladimir Prus
2009-09-18 18:25 ` Tom Tromey
2009-09-19 12:57 ` Vladimir Prus
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox