gdb
authorTom Tromey <tromey@redhat.com>
Fri, 25 Jun 2010 18:15:18 +0000 (18:15 +0000)
committerTom Tromey <tromey@redhat.com>
Fri, 25 Jun 2010 18:15:18 +0000 (18:15 +0000)
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) <execute>: 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
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/python/python.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.python/python.exp

index c696b6de9c48537981772138495f65e0a9421677..56fd929664d79cad72baaee8784640bfc9c4b4c4 100644 (file)
@@ -1,3 +1,13 @@
+2010-06-25  Tom Tromey  <tromey@redhat.com>
+
+       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) <execute>: Update.
+
 2010-06-25  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * s390-tdep.c (s390_push_dummy_call): Error on stack overflow
index 90d767a661357179a364ed394c7eedef3662c58b..47aa02dd4565109a42bfafdf8fbc73ee00d20912 100644 (file)
@@ -1,3 +1,8 @@
+2010-06-25  Tom Tromey  <tromey@redhat.com>
+
+       PR python/10808:
+       * gdb.texinfo (Basic Python): Document new gdb.execute argument.
+
 2010-06-24  Hui Zhu  <teawater@gmail.com>
 
        * gdb.texinfo: (Commands for Controlled Output): Add
index cbd636fbd91ac73ebfbc493c5726873b0112cbce..2ea143680017b0729427591fe7638663a9f589cd 100644 (file)
@@ -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
index 18b2cdc43d54e87e62ee4f1ad68e14fc9c71bf2f..b9a8cf64f1326081eb8cc0e08149ba7fdf763394 100644 (file)
@@ -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" },
index 7bfcec30bf4a74594c85e866677eba8800421754..0fcea1689fa548d0b168fd397dcb696b3663074a 100644 (file)
@@ -1,3 +1,8 @@
+2010-06-25  Tom Tromey  <tromey@redhat.com>
+
+       PR python/10808:
+       * gdb.python/python.exp: Add new tests.
+
 2010-06-25  Sami Wagiaalla  <swagiaal@redhat.com>
 
        * gdb.cp/operator.cc: Created an import loop.
index 185f45da2b85338024defd1e8c880f1f06d79eb0..d0e6c63fd21085cefcde365401620ba0013ee44c 100644 (file)
@@ -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"