From 8315665ec17eb95a2e12599d6dfb18aa45a12eb6 Mon Sep 17 00:00:00 2001 From: Yit Phang Khoo Date: Wed, 22 Aug 2012 19:15:15 +0000 Subject: [PATCH] Add a new "python-interactive" command that starts a standard Python interactive prompt with "pi" as alias, and add "py" as an alias to "python". * NEWS: Mention the new commands. * doc/gdb.texinfo (Python Commands): Document the new commands. * python/python.c (eval_python_command): New function. (python_interactive_command): For "python-interactive" with arguments, call eval_python_command. For "python-interactive" without arguments, call PyRun_InteractiveLoop. (_initialize_python): Add "python-interactive" command with "pi" as alias, and add "py" as an alias to "python". --- gdb/ChangeLog | 15 +++++++ gdb/NEWS | 8 ++++ gdb/doc/gdb.texinfo | 22 +++++++++- gdb/python/python.c | 104 +++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 145 insertions(+), 4 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index de3dbf550d6..d6e8cf65480 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,18 @@ +2012-08-22 Khoo Yit Phang + + Add a new "python-interactive" command that starts a standard + Python interactive prompt with "pi" as alias, and add "py" as + an alias to "python". + * NEWS: Mention the new commands. + * doc/gdb.texinfo (Python Commands): Document the new + commands. + * python/python.c (eval_python_command): New function. + (python_interactive_command): For "python-interactive" with + arguments, call eval_python_command. For "python-interactive" + without arguments, call PyRun_InteractiveLoop. + (_initialize_python): Add "python-interactive" command with + "pi" as alias, and add "py" as an alias to "python". + 2012-08-22 Tom Tromey * defs.h (quit_flag): Don't declare. diff --git a/gdb/NEWS b/gdb/NEWS index 942597d7220..dba6937459e 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -31,6 +31,14 @@ maint info bfds List the BFDs known to GDB. +python-interactive [command] +pi [command] + Start a Python interactive prompt, or evaluate the optional command + and print the result of expressions. + +py [command] + "py" is a new alias for "python". + * MI changes ** Command parameter changes are now notified using new async record diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 08ba92dcde5..4410a4778b7 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -22506,12 +22506,30 @@ automatically imported when @value{GDBN} starts. @cindex python commands @cindex commands to access python -@value{GDBN} provides one command for accessing the Python interpreter, +@value{GDBN} provides two commands for accessing the Python interpreter, and one related setting: @table @code +@kindex python-interactive +@kindex pi +@item python-interactive @r{[}@var{command}@r{]} +@itemx pi @r{[}@var{command}@r{]} +Without an argument, the @code{python-interactive} command can be used +to start an interactive Python prompt. + +Alternatively, a single-line Python command can be given as an +argument and evaluated. If the command is an expression, the result +will be printed; otherwise, nothing will be printed. For example: + +@smallexample +(@value{GDBP}) python-interactive 2 + 3 +5 +@end smallexample + @kindex python -@item python @r{[}@var{code}@r{]} +@kindex py +@item python @r{[}@var{command}@r{]} +@itemx py @r{[}@var{command}@r{]} The @code{python} command can be used to evaluate Python code. If given an argument, the @code{python} command will evaluate the diff --git a/gdb/python/python.c b/gdb/python/python.c index 4a2b51885b4..ad735ceaf29 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -176,6 +176,75 @@ check_quit_flag (void) return PyOS_InterruptOccurred (); } +/* Evaluate a Python command like PyRun_SimpleString, but uses + Py_single_input which prints the result of expressions, and does + not automatically print the stack on errors. */ + +static int +eval_python_command (const char *command) +{ + PyObject *m, *d, *v; + + m = PyImport_AddModule ("__main__"); + if (m == NULL) + return -1; + + d = PyModule_GetDict (m); + if (d == NULL) + return -1; + v = PyRun_StringFlags (command, Py_single_input, d, d, NULL); + if (v == NULL) + return -1; + + Py_DECREF (v); + if (Py_FlushLine ()) + PyErr_Clear (); + + return 0; +} + +/* Implementation of the gdb "python-interactive" command. */ + +static void +python_interactive_command (char *arg, int from_tty) +{ + struct cleanup *cleanup; + int err; + + cleanup = make_cleanup_restore_integer (&interpreter_async); + interpreter_async = 0; + + while (arg && *arg && isspace (*arg)) + ++arg; + + ensure_python_env (get_current_arch (), current_language); + + if (arg && *arg) + { + int len = strlen (arg); + char *script = xmalloc (len + 2); + + strcpy (script, arg); + script[len] = '\n'; + script[len + 1] = '\0'; + err = eval_python_command (script); + xfree (script); + } + else + { + err = PyRun_InteractiveLoop (instream, ""); + dont_repeat (); + } + + if (err) + { + gdbpy_print_stack (); + error (_("Error while executing Python code.")); + } + + do_cleanups (cleanup); +} + /* A wrapper around PyRun_SimpleFile. FILE is the Python script to run named FILENAME. @@ -1112,10 +1181,11 @@ gdbpy_objfiles (PyObject *unused1, PyObject *unused2) #else /* HAVE_PYTHON */ -/* Dummy implementation of the gdb "python" command. */ +/* Dummy implementation of the gdb "python-interactive" and "python" + command. */ static void -python_command (char *arg, int from_tty) +python_interactive_command (char *arg, int from_tty) { while (arg && *arg && isspace (*arg)) ++arg; @@ -1131,6 +1201,12 @@ python_command (char *arg, int from_tty) } } +static void +python_command (char *arg, int from_tty) +{ + python_interactive_command (arg, from_tty); +} + void eval_python_from_control_command (struct command_line *cmd) { @@ -1197,6 +1273,29 @@ _initialize_python (void) char *cmd_name; struct cmd_list_element *cmd; + add_com ("python-interactive", class_obscure, + python_interactive_command, +#ifdef HAVE_PYTHON + _("\ +Start a Python interactive prompt.\n\ +\n\ +Alternatively, a single-line Python command can be given as an\n\ +argument, and if the command is an expression, the result will be\n\ +printed. For example:\n\ +\n\ + (gdb) python-interactive 2 + 3\n\ + 5\n\ +") +#else /* HAVE_PYTHON */ + _("\ +Start a Python interactive prompt.\n\ +\n\ +Python scripting is not supported in this copy of GDB.\n\ +This command is only a placeholder.") +#endif /* HAVE_PYTHON */ + ); + add_com_alias ("pi", "python-interactive", class_obscure, 1); + add_com ("python", class_obscure, python_command, #ifdef HAVE_PYTHON _("\ @@ -1217,6 +1316,7 @@ Python scripting is not supported in this copy of GDB.\n\ This command is only a placeholder.") #endif /* HAVE_PYTHON */ ); + add_com_alias ("py", "python", class_obscure, 1); /* Add set/show python print-stack. */ add_prefix_cmd ("python", no_class, user_show_python, -- 2.30.2