* NEWS: Add entry for python program space support.
[deliverable/binutils-gdb.git] / gdb / python / python.c
index 50277d45d85cc1933f26109b4141043f661ea60f..935715a3fa87336385f94b90a539c15e15a32968 100644 (file)
@@ -1,6 +1,6 @@
 /* General python/gdb code
 
-   Copyright (C) 2008 Free Software Foundation, Inc.
+   Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
+#include "arch-utils.h"
 #include "command.h"
 #include "ui-out.h"
 #include "cli/cli-script.h"
 #include "gdbcmd.h"
+#include "progspace.h"
+#include "objfiles.h"
+#include "observer.h"
+#include "value.h"
+#include "language.h"
+#include "exceptions.h"
 
 #include <ctype.h>
 
    false otherwise.  */
 static int gdbpy_should_print_stack = 1;
 
+/* This is true if we should auto-load python code when an objfile is
+   opened, false otherwise.  */
+static int gdbpy_auto_load = 1;
+
 #ifdef HAVE_PYTHON
 
 #include "python.h"
@@ -36,37 +47,67 @@ static int gdbpy_should_print_stack = 1;
 #include "cli/cli-decode.h"
 #include "charset.h"
 #include "top.h"
-#include "exceptions.h"
 #include "python-internal.h"
 #include "version.h"
 #include "target.h"
 #include "gdbthread.h"
 
+static PyMethodDef GdbMethods[];
 
 PyObject *gdb_module;
 
-static PyObject *get_parameter (PyObject *, PyObject *);
-static PyObject *execute_gdb_command (PyObject *, PyObject *);
-static PyObject *gdbpy_write (PyObject *, PyObject *);
-static PyObject *gdbpy_flush (PyObject *, PyObject *);
+/* Some string constants we may wish to use.  */
+PyObject *gdbpy_to_string_cst;
+PyObject *gdbpy_children_cst;
+PyObject *gdbpy_display_hint_cst;
+PyObject *gdbpy_doc_cst;
 
-static PyMethodDef GdbMethods[] =
-{
-  { "get_value_from_history", gdbpy_get_value_from_history, METH_VARARGS,
-    "Get a value from history" },
-  { "execute", execute_gdb_command, METH_VARARGS,
-    "Execute a gdb command" },
-  { "get_parameter", get_parameter, METH_VARARGS,
-    "Return a gdb parameter's value" },
 
-  { "write", gdbpy_write, METH_VARARGS,
-    "Write a string using gdb's filtered stream." },
-  { "flush", gdbpy_flush, METH_NOARGS,
-    "Flush gdb's filtered stdout stream." },
+/* Architecture and language to be used in callbacks from
+   the Python interpreter.  */
+struct gdbarch *python_gdbarch;
+const struct language_defn *python_language;
 
-  {NULL, NULL, 0, NULL}
+/* Restore global language and architecture and Python GIL state
+   when leaving the Python interpreter.  */
+
+struct python_env
+{
+  PyGILState_STATE state;
+  struct gdbarch *gdbarch;
+  const struct language_defn *language;
 };
 
+static void
+restore_python_env (void *p)
+{
+  struct python_env *env = (struct python_env *)p;
+  PyGILState_Release (env->state);
+  python_gdbarch = env->gdbarch;
+  python_language = env->language;
+  xfree (env);
+}
+
+/* Called before entering the Python interpreter to install the
+   current language and architecture to be used for Python values.  */
+
+struct cleanup *
+ensure_python_env (struct gdbarch *gdbarch,
+                   const struct language_defn *language)
+{
+  struct python_env *env = xmalloc (sizeof *env);
+
+  env->state = PyGILState_Ensure ();
+  env->gdbarch = python_gdbarch;
+  env->language = python_language;
+
+  python_gdbarch = gdbarch;
+  python_language = language;
+
+  return make_cleanup (restore_python_env, env);
+}
+
+
 /* 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
@@ -102,23 +143,22 @@ compute_python_string (struct command_line *l)
 void
 eval_python_from_control_command (struct command_line *cmd)
 {
+  int ret;
   char *script;
   struct cleanup *cleanup;
-  PyGILState_STATE state;
 
   if (cmd->body_count != 1)
     error (_("Invalid \"python\" block structure."));
 
-  state = PyGILState_Ensure ();
-  cleanup = make_cleanup_py_restore_gil (&state);
+  cleanup = ensure_python_env (get_current_arch (), current_language);
 
   script = compute_python_string (cmd->body_list[0]);
-  PyRun_SimpleString (script);
+  ret = PyRun_SimpleString (script);
   xfree (script);
-  if (PyErr_Occurred ())
+  if (ret)
     {
       gdbpy_print_stack ();
-      error (_("error while executing Python code"));
+      error (_("Error while executing Python code."));
     }
 
   do_cleanups (cleanup);
@@ -130,20 +170,16 @@ static void
 python_command (char *arg, int from_tty)
 {
   struct cleanup *cleanup;
-  PyGILState_STATE state;
-
-  state = PyGILState_Ensure ();
-  cleanup = make_cleanup_py_restore_gil (&state);
+  cleanup = ensure_python_env (get_current_arch (), current_language);
 
   while (arg && *arg && isspace (*arg))
     ++arg;
   if (arg && *arg)
     {
-      PyRun_SimpleString (arg);
-      if (PyErr_Occurred ())
+      if (PyRun_SimpleString (arg))
        {
          gdbpy_print_stack ();
-         error (_("error while executing Python code"));
+         error (_("Error while executing Python code."));
        }
     }
   else
@@ -214,17 +250,19 @@ parameter_to_python (struct cmd_list_element *cmd)
       }
     }
 
-  return PyErr_Format (PyExc_RuntimeError, "programmer error: unhandled type");
+  return PyErr_Format (PyExc_RuntimeError, 
+                      _("Programmer error: unhandled type."));
 }
 
 /* A Python function which returns a gdb parameter's value as a Python
    value.  */
 
 static PyObject *
-get_parameter (PyObject *self, PyObject *args)
+gdbpy_parameter (PyObject *self, PyObject *args)
 {
   struct cmd_list_element *alias, *prefix, *cmd;
   char *arg, *newarg;
+  int found = -1;
   volatile struct gdb_exception except;
 
   if (! PyArg_ParseTuple (args, "s", &arg))
@@ -234,21 +272,38 @@ get_parameter (PyObject *self, PyObject *args)
 
   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);
-       }
+      found = lookup_cmd_composition (newarg, &alias, &prefix, &cmd);
     }
   xfree (newarg);
   GDB_PY_HANDLE_EXCEPTION (except);
+  if (!found)
+    return PyErr_Format (PyExc_RuntimeError,
+                        _("Could not find parameter `%s'."), arg);
 
   if (! cmd->var)
-    return PyErr_Format (PyExc_RuntimeError, "`%s' is not a variable", arg);
+    return PyErr_Format (PyExc_RuntimeError, 
+                        _("`%s' is not a parameter."), arg);
   return parameter_to_python (cmd);
 }
 
+/* Wrapper for target_charset.  */
+
+static PyObject *
+gdbpy_target_charset (PyObject *self, PyObject *args)
+{
+  const char *cset = target_charset (python_gdbarch);
+  return PyUnicode_Decode (cset, strlen (cset), host_charset (), NULL);
+}
+
+/* Wrapper for target_wide_charset.  */
+
+static PyObject *
+gdbpy_target_wide_charset (PyObject *self, PyObject *args)
+{
+  const char *cset = target_wide_charset (python_gdbarch);
+  return PyUnicode_Decode (cset, strlen (cset), host_charset (), NULL);
+}
+
 /* A Python function which evaluates a string using the gdb CLI.  */
 
 static PyObject *
@@ -256,14 +311,30 @@ execute_gdb_command (PyObject *self, PyObject *args)
 {
   struct cmd_list_element *alias, *prefix, *cmd;
   char *arg, *newarg;
+  PyObject *from_tty_obj = NULL;
+  int from_tty;
+  int cmp;
   volatile struct gdb_exception except;
 
-  if (! PyArg_ParseTuple (args, "s", &arg))
+  if (! PyArg_ParseTuple (args, "s|O!", &arg, &PyBool_Type, &from_tty_obj))
     return NULL;
 
+  from_tty = 0;
+  if (from_tty_obj)
+    {
+      cmp = PyObject_IsTrue (from_tty_obj);
+      if (cmp < 0)
+         return NULL;
+      from_tty = cmp;
+    }
+
   TRY_CATCH (except, RETURN_MASK_ALL)
     {
-      execute_command (arg, 0);
+      /* Copy the argument text in case the command modifies it.  */
+      char *copy = xstrdup (arg);
+      struct cleanup *cleanup = make_cleanup (xfree, copy);
+      execute_command (copy, from_tty);
+      do_cleanups (cleanup);
     }
   GDB_PY_HANDLE_EXCEPTION (except);
 
@@ -273,6 +344,42 @@ execute_gdb_command (PyObject *self, PyObject *args)
   Py_RETURN_NONE;
 }
 
+/* Parse a string and evaluate it as an expression.  */
+static PyObject *
+gdbpy_parse_and_eval (PyObject *self, PyObject *args)
+{
+  char *expr_str;
+  struct value *result = NULL;
+  volatile struct gdb_exception except;
+
+  if (!PyArg_ParseTuple (args, "s", &expr_str))
+    return NULL;
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      result = parse_and_eval (expr_str);
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  return value_to_value_object (result);
+}
+
+/* Read a file as Python code.  STREAM is the input file; FILE is the
+   name of the file.
+   STREAM is not closed, that is the caller's responsibility.  */
+
+void
+source_python_script (FILE *stream, const char *file)
+{
+  struct cleanup *cleanup;
+
+  cleanup = ensure_python_env (get_current_arch (), current_language);
+
+  PyRun_SimpleFile (stream, file);
+
+  do_cleanups (cleanup);
+}
+
 \f
 
 /* Printing.  */
@@ -309,6 +416,168 @@ gdbpy_print_stack (void)
     PyErr_Clear ();
 }
 
+\f
+
+/* Return the current Progspace.
+   There always is one.  */
+
+static PyObject *
+gdbpy_get_current_progspace (PyObject *unused1, PyObject *unused2)
+{
+  PyObject *result;
+
+  result = pspace_to_pspace_object (current_program_space);
+  if (result)
+    Py_INCREF (result);
+  return result;
+}
+
+/* Return a sequence holding all the Progspaces.  */
+
+static PyObject *
+gdbpy_progspaces (PyObject *unused1, PyObject *unused2)
+{
+  struct program_space *ps;
+  PyObject *list;
+
+  list = PyList_New (0);
+  if (!list)
+    return NULL;
+
+  ALL_PSPACES (ps)
+  {
+    PyObject *item = pspace_to_pspace_object (ps);
+    if (!item || PyList_Append (list, item) == -1)
+      {
+       Py_DECREF (list);
+       return NULL;
+      }
+  }
+
+  return list;
+}
+
+\f
+
+/* The "current" objfile.  This is set when gdb detects that a new
+   objfile has been loaded.  It is only set for the duration of a call
+   to gdbpy_new_objfile; it is NULL at other times.  */
+static struct objfile *gdbpy_current_objfile;
+
+/* The file name we attempt to read.  */
+#define GDBPY_AUTO_FILENAME "-gdb.py"
+
+/* This is a new_objfile observer callback which loads python code
+   based on the path to the objfile.  */
+static void
+gdbpy_new_objfile (struct objfile *objfile)
+{
+  char *realname;
+  char *filename, *debugfile;
+  int len;
+  FILE *input;
+  struct cleanup *cleanups;
+
+  if (!gdbpy_auto_load || !objfile || !objfile->name)
+    return;
+
+  cleanups = ensure_python_env (get_objfile_arch (objfile), current_language);
+
+  gdbpy_current_objfile = objfile;
+
+  realname = gdb_realpath (objfile->name);
+  len = strlen (realname);
+  filename = xmalloc (len + sizeof (GDBPY_AUTO_FILENAME));
+  memcpy (filename, realname, len);
+  strcpy (filename + len, GDBPY_AUTO_FILENAME);
+
+  input = fopen (filename, "r");
+  debugfile = filename;
+
+  make_cleanup (xfree, filename);
+  make_cleanup (xfree, realname);
+
+  if (!input && debug_file_directory)
+    {
+      /* Also try the same file in the separate debug info directory.  */
+      debugfile = xmalloc (strlen (filename)
+                          + strlen (debug_file_directory) + 1);
+      strcpy (debugfile, debug_file_directory);
+      /* FILENAME is absolute, so we don't need a "/" here.  */
+      strcat (debugfile, filename);
+
+      make_cleanup (xfree, debugfile);
+      input = fopen (debugfile, "r");
+    }
+
+  if (!input && gdb_datadir)
+    {
+      /* Also try the same file in a subdirectory of gdb's data
+        directory.  */
+      debugfile = xmalloc (strlen (gdb_datadir) + strlen (filename)
+                          + strlen ("/auto-load") + 1);
+      strcpy (debugfile, gdb_datadir);
+      strcat (debugfile, "/auto-load");
+      /* FILENAME is absolute, so we don't need a "/" here.  */
+      strcat (debugfile, filename);
+
+      make_cleanup (xfree, debugfile);
+      input = fopen (debugfile, "r");
+    }
+
+  if (input)
+    {
+      /* We don't want to throw an exception here -- but the user
+        would like to know that something went wrong.  */
+      if (PyRun_SimpleFile (input, debugfile))
+       gdbpy_print_stack ();
+      fclose (input);
+    }
+
+  do_cleanups (cleanups);
+  gdbpy_current_objfile = NULL;
+}
+
+/* Return the current Objfile, or None if there isn't one.  */
+static PyObject *
+gdbpy_get_current_objfile (PyObject *unused1, PyObject *unused2)
+{
+  PyObject *result;
+
+  if (! gdbpy_current_objfile)
+    Py_RETURN_NONE;
+
+  result = objfile_to_objfile_object (gdbpy_current_objfile);
+  if (result)
+    Py_INCREF (result);
+  return result;
+}
+
+/* Return a sequence holding all the Objfiles.  */
+
+static PyObject *
+gdbpy_objfiles (PyObject *unused1, PyObject *unused2)
+{
+  struct objfile *objf;
+  PyObject *list;
+
+  list = PyList_New (0);
+  if (!list)
+    return NULL;
+
+  ALL_OBJFILES (objf)
+  {
+    PyObject *item = objfile_to_objfile_object (objf);
+    if (!item || PyList_Append (list, item) == -1)
+      {
+       Py_DECREF (list);
+       return NULL;
+      }
+  }
+
+  return list;
+}
+
 #else /* HAVE_PYTHON */
 
 /* Dummy implementation of the gdb "python" command.  */
@@ -335,6 +604,13 @@ eval_python_from_control_command (struct command_line *cmd)
   error (_("Python scripting is not supported in this copy of GDB."));
 }
 
+void
+source_python_script (FILE *stream, const char *file)
+{
+  throw_error (UNSUPPORTED_ERROR,
+              _("Python scripting is not supported in this copy of GDB."));
+}
+
 #endif /* HAVE_PYTHON */
 
 \f
@@ -362,6 +638,9 @@ show_python (char *args, int from_tty)
 
 /* Initialize the Python code.  */
 
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+extern initialize_file_ftype _initialize_python;
+
 void
 _initialize_python (void)
 {
@@ -404,6 +683,15 @@ Enables or disables printing of Python stack traces."),
                           &set_python_list,
                           &show_python_list);
 
+  add_setshow_boolean_cmd ("auto-load", class_maintenance,
+                          &gdbpy_auto_load, _("\
+Enable or disable auto-loading of Python code when an object is opened."), _("\
+Show whether Python code will be auto-loaded when an object is opened."), _("\
+Enables or disables auto-loading of Python code when an object is opened."),
+                          NULL, NULL,
+                          &set_python_list,
+                          &show_python_list);
+
 #ifdef HAVE_PYTHON
   Py_Initialize ();
   PyEval_InitThreads ();
@@ -416,8 +704,27 @@ Enables or disables printing of Python stack traces."),
   PyModule_AddStringConstant (gdb_module, "TARGET_CONFIG", (char*) target_name);
 
   gdbpy_initialize_values ();
+  gdbpy_initialize_frames ();
+  gdbpy_initialize_commands ();
+  gdbpy_initialize_symbols ();
+  gdbpy_initialize_symtabs ();
+  gdbpy_initialize_blocks ();
+  gdbpy_initialize_functions ();
+  gdbpy_initialize_types ();
+  gdbpy_initialize_pspace ();
+  gdbpy_initialize_objfile ();
+  gdbpy_initialize_breakpoints ();
+  gdbpy_initialize_lazy_string ();
 
   PyRun_SimpleString ("import gdb");
+  PyRun_SimpleString ("gdb.pretty_printers = []");
+
+  observer_attach_new_objfile (gdbpy_new_objfile);
+
+  gdbpy_to_string_cst = PyString_FromString ("to_string");
+  gdbpy_children_cst = PyString_FromString ("children");
+  gdbpy_display_hint_cst = PyString_FromString ("display_hint");
+  gdbpy_doc_cst = PyString_FromString ("__doc__");
 
   /* Create a couple objects which are used for Python's stdout and
      stderr.  */
@@ -451,3 +758,73 @@ sys.stdout = GdbOutputFile()\n\
 
 #endif /* HAVE_PYTHON */
 }
+
+\f
+
+#if HAVE_PYTHON
+
+static PyMethodDef GdbMethods[] =
+{
+  { "history", gdbpy_history, METH_VARARGS,
+    "Get a value from history" },
+  { "execute", execute_gdb_command, METH_VARARGS,
+    "Execute a gdb command" },
+  { "parameter", gdbpy_parameter, METH_VARARGS,
+    "Return a gdb parameter's value" },
+
+  { "breakpoints", gdbpy_breakpoints, METH_NOARGS,
+    "Return a tuple of all breakpoint objects" },
+
+  { "default_visualizer", gdbpy_default_visualizer, METH_VARARGS,
+    "Find the default visualizer for a Value." },
+
+  { "current_progspace", gdbpy_get_current_progspace, METH_NOARGS,
+    "Return the current Progspace." },
+  { "progspaces", gdbpy_progspaces, METH_NOARGS,
+    "Return a sequence of all progspaces." },
+
+  { "current_objfile", gdbpy_get_current_objfile, METH_NOARGS,
+    "Return the current Objfile being loaded, or None." },
+  { "objfiles", gdbpy_objfiles, METH_NOARGS,
+    "Return a sequence of all loaded objfiles." },
+
+  { "selected_frame", gdbpy_selected_frame, METH_NOARGS,
+    "selected_frame () -> gdb.Frame.\n\
+Return the selected frame object." },
+  { "frame_stop_reason_string", gdbpy_frame_stop_reason_string, METH_VARARGS,
+    "stop_reason_string (Integer) -> String.\n\
+Return a string explaining unwind stop reason." },
+
+  { "lookup_type", (PyCFunction) gdbpy_lookup_type,
+    METH_VARARGS | METH_KEYWORDS,
+    "lookup_type (name [, block]) -> type\n\
+Return a Type corresponding to the given name." },
+  { "lookup_symbol", (PyCFunction) gdbpy_lookup_symbol,
+    METH_VARARGS | METH_KEYWORDS,
+    "lookup_symbol (name [, block] [, domain]) -> (symbol, is_field_of_this)\n\
+Return a tuple with the symbol corresponding to the given name (or None) and\n\
+a boolean indicating if name is a field of the current implied argument\n\
+`this' (when the current language is object-oriented)." },
+  { "block_for_pc", gdbpy_block_for_pc, METH_VARARGS,
+    "Return the block containing the given pc value, or None." },
+  { "parse_and_eval", gdbpy_parse_and_eval, METH_VARARGS,
+    "parse_and_eval (String) -> Value.\n\
+Parse String as an expression, evaluate it, and return the result as a Value."
+  },
+
+  { "target_charset", gdbpy_target_charset, METH_NOARGS,
+    "target_charset () -> string.\n\
+Return the name of the current target charset." },
+  { "target_wide_charset", gdbpy_target_wide_charset, METH_NOARGS,
+    "target_wide_charset () -> string.\n\
+Return the name of the current target wide charset." },
+
+  { "write", gdbpy_write, METH_VARARGS,
+    "Write a string using gdb's filtered stream." },
+  { "flush", gdbpy_flush, METH_NOARGS,
+    "Flush gdb's filtered stdout stream." },
+
+  {NULL, NULL, 0, NULL}
+};
+
+#endif /* HAVE_PYTHON */
This page took 0.029638 seconds and 4 git commands to generate.