2008-06-15 Vladimir Prus Tom Tromey Thiago Jung Bauermann Doug Evans * Makefile.in (SUBDIR_PYTHON_OBS, SUBDIR_PYTHON_SRCS, SUBDIR_PYTHON_DEPS, SUBDIR_PYTHON_LDFLAGS, SUBDIR_PYTHON_CFLAGS, PYTHON_CFLAGS): New. (python_h, python_internal_h): New. (COMMON_OBS): Add python.o. (INIT_FILES): Add python/python.c. (cli-script.o): Depend on python.h (python.o): New. * cli/cli-script.c (print_command_lines): Handle python_control. (execute_control_command): Handle python_control. (execute_control_command_suppressed): New function. (while_command): Call execute_control_command_suppressed. (if_command): Likewise. (get_command_line): Remove static attribute. (read_next_line): Handle "python". (recurse_read_control_structure): Handle python_control. (read_command_lines): Handle python_control. Include python.h. * cli/cli-script.h (get_command_line): Add prototype. (execute_control_command_suppressed): Likewise. * configure.ac: Add --with-python. * defs.h (enum command_control_type) : New constant. * python/python-internal.h: New file. * python/python.c: New file. * python/python.h: New file. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 9304bc2..09fdc34 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -254,6 +254,16 @@ SUBDIR_TUI_LDFLAGS= SUBDIR_TUI_CFLAGS= \ -DTUI=1 +# +# python sub directory definitons +# +SUBDIR_PYTHON_OBS = +SUBDIR_PYTHON_SRCS = \ + python/python.c +SUBDIR_PYTHON_DEPS = +SUBDIR_PYTHON_LDFLAGS= +SUBDIR_PYTHON_CFLAGS= + # Opcodes currently live in one of two places. Either they are in the # opcode library, typically ../opcodes, or they are in a header file @@ -963,6 +973,13 @@ tui_wingeneral_h = $(srcdir)/tui/tui-wingeneral.h tui_win_h = $(srcdir)/tui/tui-win.h $(tui_data_h) tui_winsource_h = $(srcdir)/tui/tui-winsource.h $(tui_data_h) +# +# gdb/python/ headers +# + +python_h = $(srcdir)/python/python.h $(value_h) +python_internal_h = $(srcdir)/python/python-internal.h + # gdb/features preparsed descriptions features_headers = $(defs_h) $(gdbtypes_h) $(target_descriptions_h) arm_with_iwmmxt_c = $(srcdir)/features/arm-with-iwmmxt.c $(features_headers) @@ -1081,7 +1098,8 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \ tramp-frame.o \ solib.o solib-null.o \ prologue-value.o memory-map.o xml-support.o \ - target-descriptions.o target-memory.o xml-tdesc.o xml-builtin.o + target-descriptions.o target-memory.o xml-tdesc.o xml-builtin.o \ + python.o TSOBS = inflow.o @@ -1275,7 +1293,11 @@ test-cp-name-parser$(EXEEXT): test-cp-name-parser.o $(LIBIBERTY) # duplicates. Files in the gdb/ directory can end up appearing in # COMMON_OBS (as a .o file) and CONFIG_SRCS (as a .c file). -INIT_FILES = $(COMMON_OBS) $(TSOBS) $(CONFIG_SRCS) +# NOTE: bauermann/2008-06-15: python.c needs to be explicitly included +# because the generation of init.c does not work for .c files which +# result in differently named objects (i.e., python/python -> python.o). + +INIT_FILES = $(COMMON_OBS) $(TSOBS) $(CONFIG_SRCS) python/python.c init.c: $(INIT_FILES) @echo Making init.c @rm -f init.c-tmp init.l-tmp @@ -3051,7 +3073,8 @@ cli-logging.o: $(srcdir)/cli/cli-logging.c $(defs_h) $(gdbcmd_h) $(ui_out_h) \ $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/cli/cli-logging.c cli-script.o: $(srcdir)/cli/cli-script.c $(defs_h) $(value_h) $(language_h) \ $(ui_out_h) $(gdb_string_h) $(exceptions_h) $(top_h) $(cli_cmds_h) \ - $(cli_decode_h) $(cli_script_h) $(gdb_assert_h) $(breakpoint_h) + $(cli_decode_h) $(cli_script_h) $(gdb_assert_h) $(breakpoint_h) \ + $(python_h) $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/cli/cli-script.c cli-setshow.o: $(srcdir)/cli/cli-setshow.c $(defs_h) $(readline_tilde_h) \ $(value_h) $(gdb_string_h) $(ui_out_h) $(cli_decode_h) $(cli_cmds_h) \ @@ -3375,4 +3398,19 @@ tui-winsource.o: $(srcdir)/tui/tui-winsource.c $(defs_h) $(symtab_h) \ $(gdb_curses_h) $(gdb_assert_h) $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/tui/tui-winsource.c +# +# gdb/python/ dependencies +# +# Need to explicitly specify the compile rule as make will do nothing +# or try to compile the object file into the sub-directory. + +# Flags needed to compile Python code (taken from python-config --cflags) +PYTHON_CFLAGS=-fno-strict-aliasing -DNDEBUG -fwrapv + +python.o: $(srcdir)/python/python.c $(defs_h) $(python_h) \ + $(command_h) $(libiberty_h) $(cli_decode_h) $(charset_h) $(top_h) \ + $(exceptions_h) $(python_internal_h) $(version_h) $(cli_script_h) \ + $(ui_out_h) + $(CC) -c $(INTERNAL_CFLAGS) $(PYTHON_CFLAGS) $(srcdir)/python/python.c + ### end of the gdb Makefile.in. diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c index e6fbe3f..69fd3c7 100644 --- a/gdb/cli/cli-script.c +++ b/gdb/cli/cli-script.c @@ -34,6 +34,8 @@ #include "cli/cli-script.h" #include "gdb_assert.h" +#include "python/python.h" + /* Prototypes for local functions */ static enum command_control_type @@ -102,7 +104,7 @@ build_command_line (enum command_control_type type, char *args) /* Build and return a new command structure for the control commands such as "if" and "while". */ -static struct command_line * +struct command_line * get_command_line (enum command_control_type type, char *arg) { struct command_line *cmd; @@ -225,6 +227,18 @@ print_command_lines (struct ui_out *uiout, struct command_line *cmd, continue; } + if (list->control_type == python_control) + { + ui_out_field_string (uiout, NULL, "python"); + print_command_lines (uiout, *list->body_list, depth + 1); + if (depth) + ui_out_spaces (uiout, 2 * depth); + ui_out_field_string (uiout, NULL, "end"); + ui_out_text (uiout, "\n"); + list = list->next; + continue; + } + /* ignore illegal command type and try next */ list = list->next; } /* while (list) */ @@ -527,6 +541,12 @@ execute_control_command (struct command_line *cmd) ret = commands_from_control_command (new_line, cmd); break; } + case python_control: + { + eval_python_from_control_command (cmd); + ret = simple_control; + break; + } default: warning (_("Invalid control type in canned commands structure.")); @@ -538,6 +558,17 @@ execute_control_command (struct command_line *cmd) return ret; } +/* Like execute_control_command, but first set + suppress_next_print_command_trace. */ + +enum command_control_type +execute_control_command_suppressed (struct command_line *cmd) +{ + suppress_next_print_command_trace = 1; + return execute_control_command (cmd); +} + + /* "while" command support. Executes a body of statements while the loop condition is nonzero. */ @@ -552,8 +583,7 @@ while_command (char *arg, int from_tty) if (command == NULL) return; - suppress_next_print_command_trace = 1; - execute_control_command (command); + execute_control_command_suppressed (command); free_command_lines (&command); } @@ -571,8 +601,7 @@ if_command (char *arg, int from_tty) if (command == NULL) return; - suppress_next_print_command_trace = 1; - execute_control_command (command); + execute_control_command_suppressed (command); free_command_lines (&command); } @@ -886,6 +915,12 @@ read_next_line (struct command_line **command) first_arg++; *command = build_command_line (commands_control, first_arg); } + else if (p1 - p == 6 && !strncmp (p, "python", 6)) + { + /* Note that we ignore the inline "python command" form + here. */ + *command = build_command_line (python_control, ""); + } else if (p1 - p == 10 && !strncmp (p, "loop_break", 10)) { *command = (struct command_line *) @@ -962,6 +997,7 @@ recurse_read_control_structure (struct command_line *current_cmd) { if (current_cmd->control_type == while_control || current_cmd->control_type == if_control + || current_cmd->control_type == python_control || current_cmd->control_type == commands_control) { /* Success reading an entire canned sequence of commands. */ @@ -1013,6 +1049,7 @@ recurse_read_control_structure (struct command_line *current_cmd) on it. */ if (next->control_type == while_control || next->control_type == if_control + || next->control_type == python_control || next->control_type == commands_control) { control_level++; @@ -1086,6 +1123,7 @@ read_command_lines (char *prompt_arg, int from_tty) if (next->control_type == while_control || next->control_type == if_control + || next->control_type == python_control || next->control_type == commands_control) { control_level++; diff --git a/gdb/cli/cli-script.h b/gdb/cli/cli-script.h index 42663dd..7416e1c 100644 --- a/gdb/cli/cli-script.h +++ b/gdb/cli/cli-script.h @@ -40,6 +40,12 @@ extern void show_user_1 (struct cmd_list_element *c, struct ui_file *stream); extern enum command_control_type execute_control_command (struct command_line *cmd); +extern enum command_control_type + execute_control_command_suppressed (struct command_line *cmd); + +extern struct command_line *get_command_line (enum command_control_type, + char *); + extern void print_command_lines (struct ui_out *, struct command_line *, unsigned int); diff --git a/gdb/configure.ac b/gdb/configure.ac index 101dedf..0adc9fd 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -485,6 +485,99 @@ else fi fi +dnl Utility to simplify finding libpython. +AC_DEFUN([AC_TRY_LIBPYTHON], +[ + version=$1 + define([have_libpython_var],$2) + define([VERSION],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + [HAVE_LIB]VERSION=no + AC_MSG_CHECKING([for ${version}]) + save_LIBS=$LIBS + LIBS="$LIBS -l${version}" + AC_LINK_IFELSE(AC_LANG_PROGRAM([[#include "${version}/Python.h"]], + [[Py_Initialize ();]]), + [[HAVE_LIB]VERSION=yes + have_libpython_var=yes], + [LIBS=$save_LIBS]) + AC_MSG_RESULT([$[HAVE_LIB]VERSION]) +]) + +AC_ARG_WITH(python, + AS_HELP_STRING([--with-python], [include python support (auto/yes/no/)]), + [], [with_python=auto]) +AC_MSG_CHECKING([whether to use python]) +AC_MSG_RESULT([$with_python]) + +if test "${with_python}" = no; then + AC_MSG_WARN([python support disabled; some features may be unavailable.]) + have_libpython=no +else + case "${with_python}" in + yes | auto) + # Leave as empty, use defaults. + python_includes= + python_libs= + ;; + /*) + python_includes="-I${with_python}/include" + python_libs="-L${with_python}/lib" + ;; + *) + AC_ERROR(invalid value for --with-python) + ;; + esac + + save_CPPFLAGS=$CPPFLAGS + CPPFLAGS="$CPPFLAGS ${python_includes}" + save_LIBS=$LIBS + LIBS="$LIBS ${python_libs}" + have_libpython=no + if test "${have_libpython}" = no; then + AC_TRY_LIBPYTHON(python2.6, have_libpython) + if test "${HAVE_LIBPYTHON2_6}" = yes; then + AC_DEFINE(HAVE_LIBPYTHON2_6, 1, [Define if Python 2.6 is being used.]) + fi + fi + if test ${have_libpython} = no; then + AC_TRY_LIBPYTHON(python2.5, have_libpython) + if test "${HAVE_LIBPYTHON2_5}" = yes; then + AC_DEFINE(HAVE_LIBPYTHON2_5, 1, [Define if Python 2.5 is being used.]) + fi + fi + if test ${have_libpython} = no; then + AC_TRY_LIBPYTHON(python2.4, have_libpython) + if test "${HAVE_LIBPYTHON2_4}" = yes; then + AC_DEFINE(HAVE_LIBPYTHON2_4, 1, [Define if Python 2.4 is being used.]) + fi + fi + if test ${have_libpython} = no; then + case "${with_python}" in + yes) + AC_MSG_ERROR([python is missing or unusable]) + ;; + auto) + AC_MSG_WARN([python is missing or unusable; some features may be unavailable.]) + ;; + *) + AC_MSG_ERROR([no usable python found at ${with_python}]) + ;; + esac + CPPFLAGS=$save_CPPFLAGS + LIBS=$save_LIBS + fi +fi + +if test "${have_libpython}" = yes; then + AC_DEFINE(HAVE_PYTHON, 1, [Define if Python interpreter is being linked in.]) + CONFIG_OBS="$CONFIG_OBS \$(SUBDIR_PYTHON_OBS)" + CONFIG_DEPS="$CONFIG_DEPS \$(SUBDIR_PYTHON_DEPS)" + CONFIG_SRCS="$CONFIG_SRCS \$(SUBDIR_PYTHON_SRCS)" + CONFIG_INITS="$CONFIG_INITS \$(SUBDIR_PYTHON_INITS)" + ENABLE_CFLAGS="$ENABLE_CFLAGS \$(SUBDIR_PYTHON_CFLAGS)" +fi + # ------------------------- # # Checks for header files. # # ------------------------- # diff --git a/gdb/defs.h b/gdb/defs.h index 2af40ab..98d3f7c 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -642,6 +642,7 @@ enum command_control_type while_control, if_control, commands_control, + python_control, invalid_control }; diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h new file mode 100644 index 0000000..d39724c --- /dev/null +++ b/gdb/python/python-internal.h @@ -0,0 +1,60 @@ +/* Gdb/Python header for private use by Python module. + + Copyright (C) 2008 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef GDB_PYTHON_INTERNAL_H +#define GDB_PYTHON_INTERNAL_H + +/* Python 2.4 doesn't include stdint.h soon enough to get {u,}intptr_t + needed by pyport.h. */ +#ifdef HAVE_STDINT_H +#include +#endif + +/* /usr/include/features.h on linux systems will define _POSIX_C_SOURCE + if it sees _GNU_SOURCE (which config.h will define). + pyconfig.h defines _POSIX_C_SOURCE to a different value than + /usr/include/features.h does causing compilation to fail. + To work around this, undef _POSIX_C_SOURCE before we include Python.h. */ +#undef _POSIX_C_SOURCE + +#if HAVE_LIBPYTHON2_4 +#include "python2.4/Python.h" +/* Py_ssize_t is not defined until 2.5. */ +typedef Py_intptr_t Py_ssize_t; +#elif HAVE_LIBPYTHON2_5 +#include "python2.5/Python.h" +#elif HAVE_LIBPYTHON2_6 +#include "python2.6/Python.h" +#else +#error "Unable to find usable Python.h" +#endif + +extern PyObject *gdb_module; + +/* Use this after a TRY_EXCEPT to throw the appropriate Python + exception. */ +#define GDB_PY_HANDLE_EXCEPTION(Exception) \ + do { \ + if (Exception.reason < 0) \ + return PyErr_Format (Exception.reason == RETURN_QUIT \ + ? PyExc_KeyboardInterrupt : PyExc_RuntimeError, \ + "%s", Exception.message); \ + } while (0) + +#endif /* GDB_PYTHON_INTERNAL_H */ diff --git a/gdb/python/python.c b/gdb/python/python.c new file mode 100644 index 0000000..89e136c --- /dev/null +++ b/gdb/python/python.c @@ -0,0 +1,324 @@ +/* General python/gdb code + + Copyright (C) 2008 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "defs.h" +#include "command.h" +#include "ui-out.h" +#include "cli/cli-script.h" + +#include + +#ifdef HAVE_PYTHON + +#include "python.h" +#include "libiberty.h" +#include "cli/cli-decode.h" +#include "charset.h" +#include "top.h" +#include "exceptions.h" +#include "python-internal.h" +#include "version.h" + + +PyObject *gdb_module; + +static PyObject *get_show_variable (PyObject *, PyObject *); +static PyObject *execute_gdb_command (PyObject *, PyObject *); + +static PyMethodDef GdbMethods[] = +{ + { "execute", execute_gdb_command, METH_VARARGS, + "Execute a gdb command" }, + { "show", get_show_variable, METH_VARARGS, + "Return a gdb setting's value" }, + + {NULL, NULL, 0, NULL} +}; + +/* Given a command_line, return a command string suitable for passing + to Python. Lines in the string are separated by newlines. The + return value is allocated using xmalloc and the caller is + responsible for freeing it. */ + +static char * +compute_python_string (struct command_line *l) +{ + struct command_line *iter; + char *script = NULL; + int size = 0; + int here; + + for (iter = l; iter; iter = iter->next) + size += strlen (iter->line) + 1; + + script = xmalloc (size + 1); + here = 0; + for (iter = l; iter; iter = iter->next) + { + int len = strlen (iter->line) + 1; + strcpy (&script[here], iter->line); + here += len; + script[here++] = '\n'; + } + script[here] = '\0'; + return script; +} + +void +eval_python_from_control_command (struct command_line *cmd) +{ + char *script; + + if (cmd->body_count != 1) + error (_("Invalid \"python\" block structure.")); + + script = compute_python_string (cmd->body_list[0]); + PyRun_SimpleString (script); + xfree (script); + if (PyErr_Occurred ()) + { + PyErr_Print (); + error (_("error while executing Python code")); + } +} + +/* Implementation of the gdb "python" command. */ + +static void +python_command (char *arg, int from_tty) +{ + while (arg && *arg && isspace (*arg)) + ++arg; + if (arg && *arg) + { + PyRun_SimpleString (arg); + if (PyErr_Occurred ()) + { + PyErr_Print (); + error (_("error while executing Python code")); + } + } + else + { + char *tmpbuf = xstrprintf ("Type python script"); + struct cleanup *cleanups = make_cleanup (xfree, tmpbuf); + struct command_line *l = get_command_line (python_control, ""); + cleanups = make_cleanup_free_command_lines (&l); + execute_control_command_suppressed (l); + do_cleanups (cleanups); + } +} + + + +/* Transform a gdb variable's value into a Python value. May return + NULL (and set a Python exception) on error. Helper function for + get_show_variable. */ + +static PyObject * +variable_to_python (struct cmd_list_element *cmd) +{ + switch (cmd->var_type) + { + case var_string: + case var_string_noescape: + case var_optional_filename: + case var_filename: + case var_enum: + { + char *str = * (char **) cmd->var; + if (! str) + str = ""; + return PyString_Decode (str, strlen (str), host_charset (), NULL); + } + + case var_boolean: + { + if (* (int *) cmd->var) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + } + + case var_auto_boolean: + { + enum auto_boolean ab = * (enum auto_boolean *) cmd->var; + if (ab == AUTO_BOOLEAN_TRUE) + Py_RETURN_TRUE; + else if (ab == AUTO_BOOLEAN_FALSE) + Py_RETURN_FALSE; + else + Py_RETURN_NONE; + } + + case var_integer: + if ((* (int *) cmd->var) == INT_MAX) + Py_RETURN_NONE; + /* Fall through. */ + case var_zinteger: + return PyLong_FromLong (* (int *) cmd->var); + + case var_uinteger: + { + unsigned int val = * (unsigned int *) cmd->var; + if (val == UINT_MAX) + Py_RETURN_NONE; + return PyLong_FromUnsignedLong (val); + } + } + + return PyErr_Format (PyExc_RuntimeError, "programmer error: unhandled type"); +} + +/* A Python function which returns a gdb variable's value as a Python + value. */ + +static PyObject * +get_show_variable (PyObject *self, PyObject *args) +{ + struct cmd_list_element *alias, *prefix, *cmd; + char *arg, *newarg; + volatile struct gdb_exception except; + + if (! PyArg_ParseTuple (args, "s", &arg)) + return NULL; + + newarg = concat ("show ", arg, (char *) NULL); + + TRY_CATCH (except, RETURN_MASK_ALL) + { + if (! lookup_cmd_composition (newarg, &alias, &prefix, &cmd)) + { + xfree (newarg); + return PyErr_Format (PyExc_RuntimeError, + "could not find variable `%s'", arg); + } + } + xfree (newarg); + GDB_PY_HANDLE_EXCEPTION (except); + + if (! cmd->var) + return PyErr_Format (PyExc_RuntimeError, "`%s' is not a variable", arg); + return variable_to_python (cmd); +} + +/* A Python function which evaluates a string using the gdb CLI. */ + +static PyObject * +execute_gdb_command (PyObject *self, PyObject *args) +{ + struct cmd_list_element *alias, *prefix, *cmd; + char *arg, *newarg; + volatile struct gdb_exception except; + struct cleanup *old_chain; + + if (! PyArg_ParseTuple (args, "s", &arg)) + return NULL; + + old_chain = make_cleanup (null_cleanup, 0); + + TRY_CATCH (except, RETURN_MASK_ALL) + { + execute_command (arg, 0); + } + GDB_PY_HANDLE_EXCEPTION (except); + + /* Do any commands attached to breakpoint we stopped at. Only if we + are always running synchronously. Or if we have just executed a + command that doesn't start the target. */ + if (!target_can_async_p () || !target_executing) + { + bpstat_do_actions (&stop_bpstat); + do_cleanups (old_chain); + } + + Py_RETURN_NONE; +} + + + +/* Initialize the Python code. */ + +void +_initialize_python (void) +{ + add_com ("python", class_obscure, python_command, _("\ +Evaluate a Python command.\n\ +\n\ +The command can be given as an argument, for instance:\n\ +\n\ + python print 23\n\ +\n\ +If no argument is given, the following lines are read and used\n\ +as the Python commands. Type a line containing \"end\" to indicate\n\ +the end of the command.")); + + Py_Initialize (); + + gdb_module = Py_InitModule ("gdb", GdbMethods); + + /* The casts to (char*) are for python 2.4. */ + PyModule_AddStringConstant (gdb_module, "VERSION", (char*) version); + PyModule_AddStringConstant (gdb_module, "HOST_CONFIG", (char*) host_name); + PyModule_AddStringConstant (gdb_module, "TARGET_CONFIG", (char*) target_name); + + PyRun_SimpleString ("import gdb"); +} + +#else /* HAVE_PYTHON */ + +/* Dummy implementation of the gdb "python" command. */ + +static void +python_command (char *arg, int from_tty) +{ + while (arg && *arg && isspace (*arg)) + ++arg; + if (arg && *arg) + error (_("Python scripting is not supported in this copy of GDB.")); + else + { + char *tmpbuf = xstrprintf ("Type python script"); + struct cleanup *cleanups = make_cleanup (xfree, tmpbuf); + struct command_line *l = get_command_line (python_control, ""); + cleanups = make_cleanup_free_command_lines (&l); + execute_control_command_suppressed (l); + do_cleanups (cleanups); + } +} + +void +eval_python_from_control_command (struct command_line *cmd) +{ + error (_("Python scripting is not supported in this copy of GDB.")); +} + +/* Initialize dummy Python code. */ + +void +_initialize_python (void) +{ + add_com ("python", class_obscure, python_command, _("\ +Evaluate a Python command.\n\ +\n\ +Python scripting is not supported in this copy of GDB.\n\ +This command is only a placeholder.")); +} + +#endif /* HAVE_PYTHON */ diff --git a/gdb/python/python.h b/gdb/python/python.h new file mode 100644 index 0000000..00ff159 --- /dev/null +++ b/gdb/python/python.h @@ -0,0 +1,27 @@ +/* Python/gdb header for generic use in gdb + + Copyright (C) 2008 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef GDB_PYTHON_H +#define GDB_PYTHON_H + +#include "value.h" + +void eval_python_from_control_command (struct command_line *); + +#endif /* GDB_PYTHON_H */