public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Andrew Burgess <andrew.burgess@embecosm.com>
To: gdb-patches@sourceware.org
Subject: [PATCH] gdb/python: add facility to add values into the history
Date: Fri, 20 Aug 2021 09:48:19 +0100	[thread overview]
Message-ID: <20210820084819.1503468-1-andrew.burgess@embecosm.com> (raw)

The guile API has (history-append! <value>) to add values into GDB's
history list.  There is currently no equivalent in the Python API.

This commit adds gdb.history_add(<value>) to the Python API, this
function adds <value> into the history list, and returns the index of
the new item in the history list.

The <value> can be a gdb.Value object, or anything that can be passed
to the constructor of gdb.Value.
---
 gdb/NEWS                              |  6 ++++++
 gdb/doc/python.texi                   | 14 ++++++++++++++
 gdb/python/py-value.c                 | 27 +++++++++++++++++++++++++++
 gdb/python/python-internal.h          |  1 +
 gdb/python/python.c                   |  2 ++
 gdb/testsuite/gdb.python/py-value.exp | 26 ++++++++++++++++++++++++++
 6 files changed, 76 insertions(+)

diff --git a/gdb/NEWS b/gdb/NEWS
index ec3058ea118..1436e35a4d0 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -10,6 +10,12 @@ maint show backtrace-on-fatal-signal
   fatal signal.  This only supported on some platforms where the
   backtrace and backtrace_symbols_fd functions are available.
 
+* Python API
+
+  ** New function gdb.history_add(), which takes a gdb.Value object
+     and adds the value to GDB's history list.  An integer, the index
+     of the new item in the history list is returned.
+
 *** Changes in GDB 11
 
 * The 'set disassembler-options' command now supports specifying options
diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index f4865b3d6a6..395f49229c4 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -346,6 +346,20 @@
 @code{gdb.Value} (@pxref{Values From Inferior}).
 @end defun
 
+@findex gdb.history_add
+@defun gdb.history_add (value)
+Append @var{value}, an instance of @code{gdb.Value} (@pxref{Values
+From Inferior}), to @value{GDBN}'s value history (@pxref{Value
+History}) and return an integer, its index in the history.  If
+@var{value} is not a @code{gdb.Value}, it is is converted using the
+@code{gdb.Value} constructor.  If @var{value} can't be converted to a
+@code{gdb.Value} then a @code{TypeError} is raised.
+
+When a command implemented in Python prints a single @code{gdb.Value}
+as its result, then placing the value into the history will allow the
+user convenient access to those values via CLI history facilities.
+@end defun
+
 @findex gdb.convenience_variable
 @defun gdb.convenience_variable (name)
 Return the value of the convenience variable (@pxref{Convenience
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 8df8a15f8d6..e636fbd4cb7 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -1960,6 +1960,33 @@ gdbpy_history (PyObject *self, PyObject *args)
   return value_to_value_object (res_val);
 }
 
+/* Add a gdb.Value into GDB's history, and return (as an integer) the
+   position of the newly added value.  */
+PyObject *
+gdbpy_history_add (PyObject *self, PyObject *args)
+{
+  PyObject *value_obj;
+
+  if (!PyArg_ParseTuple (args, "O", &value_obj))
+    return nullptr;
+
+  struct value *value = convert_value_from_python (value_obj);
+  if (value == nullptr)
+    return nullptr;
+
+  try
+    {
+      int idx = record_latest_value (value);
+      return gdb_py_object_from_longest (idx).release ();
+    }
+  catch (const gdb_exception &except)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+
+  return nullptr;
+}
+
 /* Return the value of a convenience variable.  */
 PyObject *
 gdbpy_convenience_variable (PyObject *self, PyObject *args)
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 690d2fb43c0..c74a60c4691 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -412,6 +412,7 @@ extern enum ext_lang_rc gdbpy_get_matching_xmethod_workers
 
 \f
 PyObject *gdbpy_history (PyObject *self, PyObject *args);
+PyObject *gdbpy_history_add (PyObject *self, PyObject *args);
 PyObject *gdbpy_convenience_variable (PyObject *self, PyObject *args);
 PyObject *gdbpy_set_convenience_variable (PyObject *self, PyObject *args);
 PyObject *gdbpy_breakpoints (PyObject *, PyObject *);
diff --git a/gdb/python/python.c b/gdb/python/python.c
index e42cbc4fd5e..351b93069a0 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -2076,6 +2076,8 @@ PyMethodDef python_GdbMethods[] =
 {
   { "history", gdbpy_history, METH_VARARGS,
     "Get a value from history" },
+  { "history_add", gdbpy_history_add, METH_VARARGS,
+    "Add a value to the value history list" },
   { "execute", (PyCFunction) execute_gdb_command, METH_VARARGS | METH_KEYWORDS,
     "execute (command [, from_tty] [, to_string]) -> [String]\n\
 Evaluate command, a string, as a gdb CLI command.  Optionally returns\n\
diff --git a/gdb/testsuite/gdb.python/py-value.exp b/gdb/testsuite/gdb.python/py-value.exp
index eca4a474727..ef0355c76b1 100644
--- a/gdb/testsuite/gdb.python/py-value.exp
+++ b/gdb/testsuite/gdb.python/py-value.exp
@@ -575,6 +575,31 @@ proc test_value_from_buffer {} {
 	   "attempt to construct value with string as type"
 }
 
+# Test the gdb.history_add API.
+proc test_add_to_history {} {
+    # Add a gdb.Value to the value history list.
+    gdb_test_no_output "python idx = gdb.history_add(gdb.Value(42))" \
+	"add value 42 to the history list"
+    gdb_test "python print (\"$%d = %s\" % (idx, gdb.history (idx)))" \
+	" = 42" "print value 42 from the history list"
+    set idx [get_python_valueof "idx" "**DEFAULT**" "get idx for value 42"]
+    gdb_test "print \$${idx}" " = 42"
+
+    # Add something to the history list that can be converted into a
+    # gdb.Value.
+    gdb_test_no_output "python idx = gdb.history_add(84)" \
+	"add value to 84 to the history list"
+    gdb_test "python print (\"$%d = %s\" % (idx, gdb.history (idx)))" \
+	" = 84" "print value 84 from the history list"
+    set idx [get_python_valueof "idx" "**DEFAULT**" "get idx for value 84"]
+    gdb_test "print \$${idx}" " = 84"
+
+    # Try adding something that can't be converted to a gdb.Value,
+    # this should give an error.
+    gdb_test "python idx = gdb.history_add(gdb.GdbError(\"an error\"))" \
+	"TypeError: Could not convert Python object: .*"
+}
+
 # Build C version of executable.  C++ is built later.
 if { [build_inferior "${binfile}" "c"] < 0 } {
     return -1
@@ -594,6 +619,7 @@ test_objfiles
 test_parse_and_eval
 test_value_hash
 test_float_conversion
+test_add_to_history
 
 # The following tests require execution.
 
-- 
2.25.4


             reply	other threads:[~2021-08-20  8:48 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-20  8:48 Andrew Burgess [this message]
2021-08-23 20:32 ` Tom Tromey
2021-08-25 17:27   ` [PATCHv2] " Andrew Burgess
2021-08-25 18:01     ` Eli Zaretskii
2021-08-26  9:20       ` Andrew Burgess
2021-08-26  9:40         ` Eli Zaretskii
2021-09-07  9:56           ` Andrew Burgess

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210820084819.1503468-1-andrew.burgess@embecosm.com \
    --to=andrew.burgess@embecosm.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).