[2/2] Add two new pretty-printer methods
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 |
fail
|
Testing failed
|
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gdb_build--master-arm |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gdb_check--master-arm |
success
|
Testing passed
|
Commit Message
This adds two new pretty-printer methods, to support random access to
children. The methods are implemented for the no-op array printer,
and DAP is updated to use this.
---
gdb/doc/python.texi | 16 ++++++++++++++++
gdb/python/lib/gdb/dap/varref.py | 22 +++++++++++++++-------
gdb/python/lib/gdb/printing.py | 9 ++++++---
3 files changed, 37 insertions(+), 10 deletions(-)
Comments
> Date: Mon, 11 Sep 2023 11:28:26 -0600
> From: Tom Tromey via Gdb-patches <gdb-patches@sourceware.org>
>
> This adds two new pretty-printer methods, to support random access to
> children. The methods are implemented for the no-op array printer,
> and DAP is updated to use this.
> ---
> gdb/doc/python.texi | 16 ++++++++++++++++
> gdb/python/lib/gdb/dap/varref.py | 22 +++++++++++++++-------
> gdb/python/lib/gdb/printing.py | 9 ++++++---
> 3 files changed, 37 insertions(+), 10 deletions(-)
>
> diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
> index d09f5e03997..79438baf477 100644
> --- a/gdb/doc/python.texi
> +++ b/gdb/doc/python.texi
> @@ -1828,6 +1828,22 @@ are peformed in this method and nothing is printed.
> If the result is not one of these types, an exception is raised.
> @end defun
>
> +@defun pretty_printer.num_children ()
> +This is not a basic method, so @value{GDBN} will only ever call it for
> +objects derived from @code{gdb.ValuePrinter}.
> +
> +If available, this method should return the number of children.
> +@code{None} may be returned if the number can't readily be computed.
> +@end defun
> +
> +@defun pretty_printer.child (n)
> +This is not a basic method, so @value{GDBN} will only ever call it for
> +objects derived from @code{gdb.ValuePrinter}.
> +
> +If available, this method should return the child value indicated by
> +@var{n}. Indices start at zero.
> +@end defun
> +
> @value{GDBN} provides a function which can be used to look up the
> default pretty-printer for a @code{gdb.Value}:
The python.texi part is OK, thanks.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
@@ -1828,6 +1828,22 @@ are peformed in this method and nothing is printed.
If the result is not one of these types, an exception is raised.
@end defun
+@defun pretty_printer.num_children ()
+This is not a basic method, so @value{GDBN} will only ever call it for
+objects derived from @code{gdb.ValuePrinter}.
+
+If available, this method should return the number of children.
+@code{None} may be returned if the number can't readily be computed.
+@end defun
+
+@defun pretty_printer.child (n)
+This is not a basic method, so @value{GDBN} will only ever call it for
+objects derived from @code{gdb.ValuePrinter}.
+
+If available, this method should return the child value indicated by
+@var{n}. Indices start at zero.
+@end defun
+
@value{GDBN} provides a function which can be used to look up the
default pretty-printer for a @code{gdb.Value}:
@@ -151,9 +151,9 @@ class VariableReference(BaseReference):
# This discards all laziness. This could be improved
# slightly by lazily evaluating children, but because this
# code also generally needs to know the number of
- # children, it probably wouldn't help much. A real fix
- # would require an update to gdb's pretty-printer protocol
- # (though of course that is probably also inadvisable).
+ # children, it probably wouldn't help much. Note that
+ # this is only needed with legacy (non-ValuePrinter)
+ # printers.
self.child_cache = list(self.printer.children())
return self.child_cache
@@ -161,9 +161,12 @@ class VariableReference(BaseReference):
if self.count is None:
return None
if self.count == -1:
- if hasattr(self.printer, "num_children"):
- num_children = self.printer.num_children
- else:
+ num_children = None
+ if isinstance(self.printer, gdb.ValuePrinter) and hasattr(
+ self.printer, "num_children"
+ ):
+ num_children = self.printer.num_children()
+ if num_children is None:
num_children = len(self.cache_children())
self.count = num_children
return self.count
@@ -193,7 +196,12 @@ class VariableReference(BaseReference):
@in_gdb_thread
def fetch_one_child(self, idx):
- return self.cache_children()[idx]
+ if isinstance(self.printer, gdb.ValuePrinter) and hasattr(
+ self.printer, "child"
+ ):
+ return self.printer.child(idx)
+ else:
+ return self.cache_children()[idx]
@in_gdb_thread
@@ -299,9 +299,6 @@ class NoOpArrayPrinter(gdb.ValuePrinter):
e_values = itertools.takewhile(lambda x: x.enumval <= high, e_values)
low = 0
high = len(list(e_values)) - 1
- # This is a convenience to the DAP code and perhaps other
- # users.
- self.num_children = high - low + 1
self.__low = low
self.__high = high
@@ -311,6 +308,12 @@ class NoOpArrayPrinter(gdb.ValuePrinter):
def display_hint(self):
return "array"
+ def num_children(self):
+ return self.__high - self.__low + 1
+
+ def child(self, i):
+ return (self.__low + i, self.__value[self.__low + i])
+
def children(self):
for i in range(self.__low, self.__high + 1):
yield (i, self.__value[i])