From bc9f0842f1f46aa754b20c5f2e12e2fa035041e3 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Fri, 25 Jun 2010 18:15:18 +0000 Subject: [PATCH] gdb PR python/10808: * python/python.c (execute_gdb_command): Add keywords. Accept "to_string" argument. (struct restore_ui_file_closure): New. (restore_ui_file): New function. (make_cleanup_restore_ui_file): Likewise. (GdbMethods) : Update. gdb/doc PR python/10808: * gdb.texinfo (Basic Python): Document new gdb.execute argument. gdb/testsuite PR python/10808: * gdb.python/python.exp: Add new tests. --- gdb/ChangeLog | 10 ++++ gdb/doc/ChangeLog | 5 ++ gdb/doc/gdb.texinfo | 9 +++- gdb/python/python.c | 80 ++++++++++++++++++++++++++--- gdb/testsuite/ChangeLog | 5 ++ gdb/testsuite/gdb.python/python.exp | 4 ++ 6 files changed, 103 insertions(+), 10 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index c696b6de9c..56fd929664 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2010-06-25 Tom Tromey + + PR python/10808: + * python/python.c (execute_gdb_command): Add keywords. Accept + "to_string" argument. + (struct restore_ui_file_closure): New. + (restore_ui_file): New function. + (make_cleanup_restore_ui_file): Likewise. + (GdbMethods) : Update. + 2010-06-25 Ulrich Weigand * s390-tdep.c (s390_push_dummy_call): Error on stack overflow diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 90d767a661..47aa02dd45 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,8 @@ +2010-06-25 Tom Tromey + + PR python/10808: + * gdb.texinfo (Basic Python): Document new gdb.execute argument. + 2010-06-24 Hui Zhu * gdb.texinfo: (Commands for Controlled Output): Add diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index cbd636fbd9..2ea1436800 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -20200,15 +20200,20 @@ methods and classes added by @value{GDBN} are placed in this module. use in all scripts evaluated by the @code{python} command. @findex gdb.execute -@defun execute command [from_tty] +@defun execute command [from_tty] [to_string] Evaluate @var{command}, a string, as a @value{GDBN} CLI command. If a GDB exception happens while @var{command} runs, it is translated as described in @ref{Exception Handling,,Exception Handling}. -If no exceptions occur, this function returns @code{None}. @var{from_tty} specifies whether @value{GDBN} ought to consider this command as having originated from the user invoking it interactively. It must be a boolean value. If omitted, it defaults to @code{False}. + +By default, any output produced by @var{command} is sent to +@value{GDBN}'s standard output. If the @var{to_string} parameter is +@code{True}, then output will be collected by @code{gdb.execute} and +returned as a string. The default is @code{False}, in which case the +return value is @code{None}. @end defun @findex gdb.breakpoints diff --git a/gdb/python/python.c b/gdb/python/python.c index 18b2cdc43d..b9a8cf64f1 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -309,36 +309,94 @@ gdbpy_target_wide_charset (PyObject *self, PyObject *args) return PyUnicode_Decode (cset, strlen (cset), host_charset (), NULL); } +struct restore_ui_file_closure +{ + struct ui_file **variable; + struct ui_file *value; +}; + +static void +restore_ui_file (void *p) +{ + struct restore_ui_file_closure *closure = p; + + *(closure->variable) = closure->value; +} + +/* Remember the current value of *VARIABLE and make it restored when + the cleanup is run. */ +struct cleanup * +make_cleanup_restore_ui_file (struct ui_file **variable) +{ + struct restore_ui_file_closure *c = XNEW (struct restore_ui_file_closure); + + c->variable = variable; + c->value = *variable; + + return make_cleanup_dtor (restore_ui_file, (void *) c, xfree); +} + /* A Python function which evaluates a string using the gdb CLI. */ static PyObject * -execute_gdb_command (PyObject *self, PyObject *args) +execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw) { char *arg; - PyObject *from_tty_obj = NULL; - int from_tty; - int cmp; + PyObject *from_tty_obj = NULL, *to_string_obj = NULL; + int from_tty, to_string; volatile struct gdb_exception except; + static char *keywords[] = {"command", "from_tty", "to_string", NULL }; + char *result = NULL; - if (! PyArg_ParseTuple (args, "s|O!", &arg, &PyBool_Type, &from_tty_obj)) + if (! PyArg_ParseTupleAndKeywords (args, kw, "s|O!O!", keywords, &arg, + &PyBool_Type, &from_tty_obj, + &PyBool_Type, &to_string_obj)) return NULL; from_tty = 0; if (from_tty_obj) { - cmp = PyObject_IsTrue (from_tty_obj); + int cmp = PyObject_IsTrue (from_tty_obj); if (cmp < 0) - return NULL; + return NULL; from_tty = cmp; } + to_string = 0; + if (to_string_obj) + { + int cmp = PyObject_IsTrue (to_string_obj); + if (cmp < 0) + return NULL; + to_string = cmp; + } + TRY_CATCH (except, RETURN_MASK_ALL) { /* Copy the argument text in case the command modifies it. */ char *copy = xstrdup (arg); struct cleanup *cleanup = make_cleanup (xfree, copy); + struct ui_file *str_file = NULL; + + if (to_string) + { + str_file = mem_fileopen (); + + make_cleanup_restore_ui_file (&gdb_stdout); + make_cleanup_restore_ui_file (&gdb_stderr); + make_cleanup_ui_file_delete (str_file); + + gdb_stdout = str_file; + gdb_stderr = str_file; + } execute_command (copy, from_tty); + + if (str_file) + result = ui_file_xstrdup (str_file, NULL); + else + result = NULL; + do_cleanups (cleanup); } GDB_PY_HANDLE_EXCEPTION (except); @@ -346,6 +404,12 @@ execute_gdb_command (PyObject *self, PyObject *args) /* Do any commands attached to breakpoint we stopped at. */ bpstat_do_actions (); + if (result) + { + PyObject *r = PyString_FromString (result); + xfree (result); + return r; + } Py_RETURN_NONE; } @@ -758,7 +822,7 @@ static PyMethodDef GdbMethods[] = { { "history", gdbpy_history, METH_VARARGS, "Get a value from history" }, - { "execute", execute_gdb_command, METH_VARARGS, + { "execute", (PyCFunction) execute_gdb_command, METH_VARARGS | METH_KEYWORDS, "Execute a gdb command" }, { "parameter", gdbpy_parameter, METH_VARARGS, "Return a gdb parameter's value" }, diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 7bfcec30bf..0fcea1689f 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-06-25 Tom Tromey + + PR python/10808: + * gdb.python/python.exp: Add new tests. + 2010-06-25 Sami Wagiaalla * gdb.cp/operator.cc: Created an import loop. diff --git a/gdb/testsuite/gdb.python/python.exp b/gdb/testsuite/gdb.python/python.exp index 185f45da2b..d0e6c63fd2 100644 --- a/gdb/testsuite/gdb.python/python.exp +++ b/gdb/testsuite/gdb.python/python.exp @@ -83,3 +83,7 @@ gdb_test "python print gdb.objfiles()" "\\\[\\\]" # Test http://bugs.python.org/issue4434 workaround in configure.ac gdb_test "python import itertools; print 'IMPOR'+'TED'" "IMPORTED" "pythonX.Y/lib-dynload/*.so" + +gdb_test_no_output \ + "python x = gdb.execute('printf \"%d\", 23', to_string = True)" +gdb_test "python print x" "23" -- 2.34.1