* NEWS: Add entry for python program space support.
authorDoug Evans <dje@google.com>
Thu, 15 Apr 2010 19:54:13 +0000 (19:54 +0000)
committerDoug Evans <dje@google.com>
Thu, 15 Apr 2010 19:54:13 +0000 (19:54 +0000)
* Makefile.in (SUBDIR_PYTHON_OBS): Add py-progspace.o.
(SUBDIR_PYTHON_SRCS): Add py-progspace.c.
(py-progspace.o): New rule.
* python/py-prettyprint.c (find_pretty_printer_from_objfiles): New
function.
(find_pretty_printer_from_progspace): New function.
(find_pretty_printer_from_gdb): New function.
(find_pretty_printer): Rewrite.
* python/py-progspace.c: New file.
* python/python-internal.h (program_space): Add forward decl.
(pspace_to_pspace_object, pspy_get_printers): Declare.
(gdbpy_initialize_pspace): Declare.
* python/python.c: #include "progspace.h".
(gdbpy_get_current_progspace, gdbpy_progspaces): New functions.
(_initialize_python): Call gdbpy_initialize_pspace.
(GdbMethods): Add current_progspace, progspaces.

doc/
* gdb.texinfo (Python API): Add progspaces section.
(Selecting Pretty-Printers): Progspace pretty-printers are
searched too.
(Progspaces In Python): New section.

testsuite/
* gdb.python/py-progspace.c: New file.
* gdb.python/py-progspace.exp: New file.

12 files changed:
gdb/ChangeLog
gdb/Makefile.in
gdb/NEWS
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/python/py-prettyprint.c
gdb/python/py-progspace.c [new file with mode: 0644]
gdb/python/python-internal.h
gdb/python/python.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.python/py-progspace.c [new file with mode: 0644]
gdb/testsuite/gdb.python/py-progspace.exp [new file with mode: 0644]

index d4d26be64c5c71a43d3caed002a5f17c6449dcc9..efa7360517d7d0f198f5a08b2c2ac98a41708b83 100644 (file)
@@ -1,5 +1,23 @@
 2010-04-15  Doug Evans  <dje@google.com>
 
+       * NEWS: Add entry for python program space support.
+       * Makefile.in (SUBDIR_PYTHON_OBS): Add py-progspace.o.
+       (SUBDIR_PYTHON_SRCS): Add py-progspace.c.
+       (py-progspace.o): New rule.
+       * python/py-prettyprint.c (find_pretty_printer_from_objfiles): New
+       function.
+       (find_pretty_printer_from_progspace): New function.
+       (find_pretty_printer_from_gdb): New function.
+       (find_pretty_printer): Rewrite.
+       * python/py-progspace.c: New file.
+       * python/python-internal.h (program_space): Add forward decl.
+       (pspace_to_pspace_object, pspy_get_printers): Declare.
+       (gdbpy_initialize_pspace): Declare.
+       * python/python.c: #include "progspace.h".
+       (gdbpy_get_current_progspace, gdbpy_progspaces): New functions.
+       (_initialize_python): Call gdbpy_initialize_pspace.
+       (GdbMethods): Add current_progspace, progspaces.
+
        Add -s option to source command.
        * NEWS: Document new option.
        * cli/cli-cmds.c (find_and_open_script): Add function comment.
index b507d3e109875f43fa7926b02cb403396c09e436..fc16fbf8d2c38f2d7462be846acf2d59766c6df6 100644 (file)
@@ -275,6 +275,7 @@ SUBDIR_PYTHON_OBS = \
        py-lazy-string.o \
        py-objfile.o \
        py-prettyprint.o \
+       py-progspace.o \
        py-symbol.o \
        py-symtab.o \
        py-type.o \
@@ -290,6 +291,7 @@ SUBDIR_PYTHON_SRCS = \
        python/py-lazy-string.c \
        python/py-objfile.c \
        python/py-prettyprint.c \
+       python/py-progspace.c \
        python/py-symbol.c \
        python/py-symtab.c \
        python/py-type.c \
@@ -2016,6 +2018,10 @@ py-prettyprint.o: $(srcdir)/python/py-prettyprint.c
        $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-prettyprint.c
        $(POSTCOMPILE)
 
+py-progspace.o: $(srcdir)/python/py-progspace.c
+       $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-progspace.c
+       $(POSTCOMPILE)
+
 py-symbol.o: $(srcdir)/python/py-symbol.c
        $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-symbol.c
        $(POSTCOMPILE)
index a5488e945b135bce460dca6ae90afeb74697a1df..936987358a0cf4786aaa3351ec3bc4ef4e03cf63 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
 * Python scripting
 
 ** The GDB Python API now has access to breakpoints, symbols, symbol
-   tables, and frame's code blocks.
+   tables, program spaces, and frame's code blocks.
 
-** New methods gdb.target_charset and gdb.target_wide_charset.
+** New functions gdb.target_charset, gdb.target_wide_charset,
+   gdb.progspaces, and gdb.current_progspace.
+
+** Pretty-printers are now also looked up in the current program space.
 
 * Tracepoint actions were unified with breakpoint commands. In particular,
 there are no longer differences in "info break" output for breakpoints and
index ce9092f8b70f80393a4c1ce5df0c61e07f34d791..0260d1e0333252f5560a8de342b1711703f97c05 100644 (file)
@@ -1,5 +1,10 @@
 2010-04-15  Doug Evans  <dje@google.com>
 
+       * gdb.texinfo (Python API): Add progspaces section.
+       (Selecting Pretty-Printers): Progspace pretty-printers are
+       searched too.
+       (Progspaces In Python): New section.
+
        * gdb.texinfo (Command Files): Add docs for new "source -s" option.
 
 2010-04-14  Phil Muldoon  <pmuldoon@redhat.com>
index 749e975a9729f491cc7cb77b2269a3e3070d29a9..8a224e0b30c93b85754bbb4f20c035ec49a632f3 100644 (file)
@@ -19723,6 +19723,7 @@ situation, a Python @code{KeyboardInterrupt} exception is thrown.
 * Selecting Pretty-Printers::   How GDB chooses a pretty-printer.
 * Commands In Python::          Implementing new commands in Python.
 * Functions In Python::         Writing new convenience functions.
+* Progspaces In Python::        Program spaces.
 * Objfiles In Python::          Object files.
 * Frames In Python::            Accessing inferior stack frames from Python.
 * Blocks In Python::            Accessing frame blocks from Python.
@@ -20461,6 +20462,7 @@ If the result is not one of these types, an exception is raised.
 
 The Python list @code{gdb.pretty_printers} contains an array of
 functions that have been registered via addition as a pretty-printer.
+Each @code{gdb.Progspace} contains a @code{pretty_printers} attribute.
 Each @code{gdb.Objfile} also contains a @code{pretty_printers}
 attribute.
 
@@ -20471,8 +20473,12 @@ cannot create a pretty-printer for the value, it should return
 @code{None}.
 
 @value{GDBN} first checks the @code{pretty_printers} attribute of each
-@code{gdb.Objfile} and iteratively calls each function in the list for
-that @code{gdb.Objfile} until it receives a pretty-printer object.
+@code{gdb.Objfile} in the current program space and iteratively calls
+each function in the list for that @code{gdb.Objfile} until it receives
+a pretty-printer object.
+If no pretty-printer is found in the objfile lists, @value{GDBN} then
+searches the pretty-printer list of the current program space,
+calling each function until an object is returned.
 After these lists have been exhausted, it tries the global
 @code{gdb.pretty-printers} list, again calling each function until an
 object is returned.
@@ -20870,6 +20876,49 @@ registration of the function with @value{GDBN}.  Depending on how the
 Python code is read into @value{GDBN}, you may need to import the
 @code{gdb} module explicitly.
 
+@node Progspaces In Python
+@subsubsection Program Spaces In Python
+
+@cindex progspaces in python
+@tindex gdb.Progspace
+@tindex Progspace
+A program space, or @dfn{progspace}, represents a symbolic view
+of an address space.
+It consists of all of the objfiles of the program.
+@xref{Objfiles In Python}.
+@xref{Inferiors and Programs, program spaces}, for more details
+about program spaces.
+
+The following progspace-related functions are available in the
+@code{gdb} module:
+
+@findex gdb.current_progspace
+@defun current_progspace
+This function returns the program space of the currently selected inferior.
+@xref{Inferiors and Programs}.
+@end defun
+
+@findex gdb.progspaces
+@defun progspaces
+Return a sequence of all the progspaces currently known to @value{GDBN}.
+@end defun
+
+Each progspace is represented by an instance of the @code{gdb.Progspace}
+class.
+
+@defivar Progspace filename
+The file name of the progspace as a string.
+@end defivar
+
+@defivar Progspace pretty_printers
+The @code{pretty_printers} attribute is a list of functions.  It is
+used to look up pretty-printers.  A @code{Value} is passed to each
+function in order; if the function returns @code{None}, then the
+search continues.  Otherwise, the return value should be an object
+which is used to format the value.  @xref{Pretty Printing}, for more
+information.
+@end defivar
+
 @node Objfiles In Python
 @subsubsection Objfiles In Python
 
index 9f9fea15274b2e8eebb011dfb9dd6c9914000e23..d26ed581ea984eba0ebc78146c13a1b596ae2a52 100644 (file)
 #ifdef HAVE_PYTHON
 #include "python-internal.h"
 
-
 /* Helper function for find_pretty_printer which iterates over a list,
    calls each function and inspects output.  This will return a
    printer object if one recognizes VALUE.  If no printer is found, it
    will return None.  On error, it will set the Python error and
    return NULL.  */
+
 static PyObject *
 search_pp_list (PyObject *list, PyObject *value)
 {
@@ -60,18 +60,19 @@ search_pp_list (PyObject *list, PyObject *value)
   Py_RETURN_NONE;
 }
 
-/* Find the pretty-printing constructor function for VALUE.  If no
-   pretty-printer exists, return None.  If one exists, return a new
-   reference.  On error, set the Python error and return NULL.  */
+/* Subroutine of find_pretty_printer to simplify it.
+   Look for a pretty-printer to print VALUE in all objfiles.
+   The result is NULL if there's an error and the search should be terminated.
+   The result is Py_None, suitably inc-ref'd, if no pretty-printer was found.
+   Otherwise the result is the pretty-printer function, suitably inc-ref'd.  */
+
 static PyObject *
-find_pretty_printer (PyObject *value)
+find_pretty_printer_from_objfiles (PyObject *value)
 {
-  PyObject *pp_list = NULL;
-  PyObject *function = NULL;
+  PyObject *pp_list;
+  PyObject *function;
   struct objfile *obj;
-  volatile struct gdb_exception except;
 
-  /* Look at the pretty-printer dictionary for each objfile.  */
   ALL_OBJFILES (obj)
   {
     PyObject *objf = objfile_to_objfile_object (obj);
@@ -84,44 +85,95 @@ find_pretty_printer (PyObject *value)
 
     pp_list = objfpy_get_printers (objf, NULL);
     function = search_pp_list (pp_list, value);
+    Py_XDECREF (pp_list);
 
-    /* If there is an error in any objfile list, abort the search and
-       exit.  */
+    /* If there is an error in any objfile list, abort the search and exit.  */
     if (! function)
-      {
-       Py_XDECREF (pp_list);
-       return NULL;
-      }
+      return NULL;
 
     if (function != Py_None)
-      goto done;
+      return function;
     
     Py_DECREF (function);
-    Py_XDECREF (pp_list);
   }
 
-  pp_list = NULL;
+  Py_RETURN_NONE;
+}
+
+/* Subroutine of find_pretty_printer to simplify it.
+   Look for a pretty-printer to print VALUE in the current program space.
+   The result is NULL if there's an error and the search should be terminated.
+   The result is Py_None, suitably inc-ref'd, if no pretty-printer was found.
+   Otherwise the result is the pretty-printer function, suitably inc-ref'd.  */
+
+static PyObject *
+find_pretty_printer_from_progspace (PyObject *value)
+{
+  PyObject *pp_list;
+  PyObject *function;
+  PyObject *obj = pspace_to_pspace_object (current_program_space);
+
+  if (!obj)
+    return NULL;
+  pp_list = pspy_get_printers (obj, NULL);
+  function = search_pp_list (pp_list, value);
+  Py_XDECREF (pp_list);
+  return function;
+}
+
+/* Subroutine of find_pretty_printer to simplify it.
+   Look for a pretty-printer to print VALUE in the gdb module.
+   The result is NULL if there's an error and the search should be terminated.
+   The result is Py_None, suitably inc-ref'd, if no pretty-printer was found.
+   Otherwise the result is the pretty-printer function, suitably inc-ref'd.  */
+
+static PyObject *
+find_pretty_printer_from_gdb (PyObject *value)
+{
+  PyObject *pp_list;
+  PyObject *function;
+
   /* Fetch the global pretty printer dictionary.  */
   if (! PyObject_HasAttrString (gdb_module, "pretty_printers"))
+    Py_RETURN_NONE;
+  pp_list = PyObject_GetAttrString (gdb_module, "pretty_printers");
+  if (pp_list == NULL || ! PyList_Check (pp_list))
     {
-      function = Py_None;
-      Py_INCREF (function);
-      goto done;
+      Py_XDECREF (pp_list);
+      Py_RETURN_NONE;
     }
-  pp_list = PyObject_GetAttrString (gdb_module, "pretty_printers");
-  if (! pp_list)
-    goto done;
-  if (! PyList_Check (pp_list))
-    goto done;
 
   function = search_pp_list (pp_list, value);
-
- done:
   Py_XDECREF (pp_list);
-  
   return function;
 }
 
+/* Find the pretty-printing constructor function for VALUE.  If no
+   pretty-printer exists, return None.  If one exists, return a new
+   reference.  On error, set the Python error and return NULL.  */
+
+static PyObject *
+find_pretty_printer (PyObject *value)
+{
+  PyObject *function;
+
+  /* Look at the pretty-printer dictionary for each objfile
+     in the current program-space.  */
+  function = find_pretty_printer_from_objfiles (value);
+  if (function == NULL || function != Py_None)
+    return function;
+  Py_DECREF (function);
+
+  /* Look at the pretty-printer dictionary for the current program-space.  */
+  function = find_pretty_printer_from_progspace (value);
+  if (function == NULL || function != Py_None)
+    return function;
+  Py_DECREF (function);
+
+  /* Look at the pretty-printer dictionary in the gdb module.  */
+  function = find_pretty_printer_from_gdb (value);
+  return function;
+}
 
 /* Pretty-print a single value, via the printer object PRINTER.
    If the function returns a string, a PyObject containing the string
diff --git a/gdb/python/py-progspace.c b/gdb/python/py-progspace.c
new file mode 100644 (file)
index 0000000..1460878
--- /dev/null
@@ -0,0 +1,240 @@
+/* Python interface to program spaces.
+
+   Copyright (C) 2010 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 <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "python-internal.h"
+#include "charset.h"
+#include "progspace.h"
+#include "objfiles.h"
+#include "language.h"
+
+typedef struct
+{
+  PyObject_HEAD
+
+  /* The corresponding pspace.  */
+  struct program_space *pspace;
+
+  /* The pretty-printer list of functions.  */
+  PyObject *printers;
+} pspace_object;
+
+static PyTypeObject pspace_object_type;
+
+static const struct program_space_data *pspy_pspace_data_key;
+
+\f
+
+/* An Objfile method which returns the objfile's file name, or None.  */
+
+static PyObject *
+pspy_get_filename (PyObject *self, void *closure)
+{
+  pspace_object *obj = (pspace_object *) self;
+  if (obj->pspace)
+    {
+      struct objfile *objfile = obj->pspace->symfile_object_file;
+      if (objfile && objfile->name)
+       return PyString_Decode (objfile->name, strlen (objfile->name),
+                               host_charset (), NULL);
+    }
+  Py_RETURN_NONE;
+}
+
+static void
+pspy_dealloc (PyObject *self)
+{
+  pspace_object *ps_self = (pspace_object *) self;
+  Py_XDECREF (ps_self->printers);
+  self->ob_type->tp_free (self);
+}
+
+static PyObject *
+pspy_new (PyTypeObject *type, PyObject *args, PyObject *keywords)
+{
+  pspace_object *self = (pspace_object *) type->tp_alloc (type, 0);
+  if (self)
+    {
+      self->pspace = NULL;
+
+      self->printers = PyList_New (0);
+      if (!self->printers)
+       {
+         Py_DECREF (self);
+         return NULL;
+       }
+    }
+  return (PyObject *) self;
+}
+
+PyObject *
+pspy_get_printers (PyObject *o, void *ignore)
+{
+  pspace_object *self = (pspace_object *) o;
+  Py_INCREF (self->printers);
+  return self->printers;
+}
+
+static int
+pspy_set_printers (PyObject *o, PyObject *value, void *ignore)
+{
+  PyObject *tmp;
+  pspace_object *self = (pspace_object *) o;
+  if (! value)
+    {
+      PyErr_SetString (PyExc_TypeError,
+                      "cannot delete the pretty_printers attribute");
+      return -1;
+    }
+
+  if (! PyList_Check (value))
+    {
+      PyErr_SetString (PyExc_TypeError,
+                      "the pretty_printers attribute must be a list");
+      return -1;
+    }
+
+  /* Take care in case the LHS and RHS are related somehow.  */
+  tmp = self->printers;
+  Py_INCREF (value);
+  self->printers = value;
+  Py_XDECREF (tmp);
+
+  return 0;
+}
+
+\f
+
+/* Clear the PSPACE pointer in a Pspace object and remove the reference.  */
+
+static void
+py_free_pspace (struct program_space *pspace, void *datum)
+{
+  struct cleanup *cleanup;
+  pspace_object *object = datum;
+  /* FIXME: What's the right way to get a program space's arch?
+     There may be multiple.  */
+  struct gdbarch *arch = get_objfile_arch (pspace->symfile_object_file);
+
+  cleanup = ensure_python_env (arch, current_language);
+  object->pspace = NULL;
+  Py_DECREF ((PyObject *) object);
+  do_cleanups (cleanup);
+}
+
+/* Return a borrowed reference to the Python object of type Pspace
+   representing PSPACE.  If the object has already been created,
+   return it.  Otherwise, create it.  Return NULL and set the Python
+   error on failure.  */
+
+PyObject *
+pspace_to_pspace_object (struct program_space *pspace)
+{
+  pspace_object *object;
+
+  object = program_space_data (pspace, pspy_pspace_data_key);
+  if (!object)
+    {
+      object = PyObject_New (pspace_object, &pspace_object_type);
+      if (object)
+       {
+         PyObject *dict;
+
+         object->pspace = pspace;
+
+         object->printers = PyList_New (0);
+         if (!object->printers)
+           {
+             Py_DECREF (object);
+             return NULL;
+           }
+
+         set_program_space_data (pspace, pspy_pspace_data_key, object);
+       }
+    }
+
+  return (PyObject *) object;
+}
+
+void
+gdbpy_initialize_pspace (void)
+{
+  pspy_pspace_data_key
+    = register_program_space_data_with_cleanup (py_free_pspace);
+
+  if (PyType_Ready (&pspace_object_type) < 0)
+    return;
+
+  Py_INCREF (&pspace_object_type);
+  PyModule_AddObject (gdb_module, "Progspace", (PyObject *) &pspace_object_type);
+}
+
+\f
+
+static PyGetSetDef pspace_getset[] =
+{
+  { "filename", pspy_get_filename, NULL,
+    "The progspace's main filename, or None.", NULL },
+  { "pretty_printers", pspy_get_printers, pspy_set_printers,
+    "Pretty printers.", NULL },
+  { NULL }
+};
+
+static PyTypeObject pspace_object_type =
+{
+  PyObject_HEAD_INIT (NULL)
+  0,                             /*ob_size*/
+  "gdb.Progspace",               /*tp_name*/
+  sizeof (pspace_object),        /*tp_basicsize*/
+  0,                             /*tp_itemsize*/
+  pspy_dealloc,                          /*tp_dealloc*/
+  0,                             /*tp_print*/
+  0,                             /*tp_getattr*/
+  0,                             /*tp_setattr*/
+  0,                             /*tp_compare*/
+  0,                             /*tp_repr*/
+  0,                             /*tp_as_number*/
+  0,                             /*tp_as_sequence*/
+  0,                             /*tp_as_mapping*/
+  0,                             /*tp_hash */
+  0,                             /*tp_call*/
+  0,                             /*tp_str*/
+  0,                             /*tp_getattro*/
+  0,                             /*tp_setattro*/
+  0,                             /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT,            /*tp_flags*/
+  "GDB progspace object",        /* tp_doc */
+  0,                             /* tp_traverse */
+  0,                             /* tp_clear */
+  0,                             /* tp_richcompare */
+  0,                             /* tp_weaklistoffset */
+  0,                             /* tp_iter */
+  0,                             /* tp_iternext */
+  0,                             /* tp_methods */
+  0,                             /* tp_members */
+  pspace_getset,                 /* tp_getset */
+  0,                             /* tp_base */
+  0,                             /* tp_dict */
+  0,                             /* tp_descr_get */
+  0,                             /* tp_descr_set */
+  0,                             /* tp_dictoffset */
+  0,                             /* tp_init */
+  0,                             /* tp_alloc */
+  pspy_new,                      /* tp_new */
+};
index 98d2b3f2b9d4b7dd2ee8d2633bdb62b4ac879f3a..e3368e368c5b1bd36fa2f3e92531790e01b02b2e 100644 (file)
@@ -68,6 +68,7 @@ typedef int Py_ssize_t;
 struct block;
 struct value;
 struct language_defn;
+struct program_space;
 
 extern PyObject *gdb_module;
 extern PyTypeObject value_object_type;
@@ -91,8 +92,11 @@ PyObject *symbol_to_symbol_object (struct symbol *sym);
 PyObject *block_to_block_object (struct block *block, struct objfile *objfile);
 PyObject *value_to_value_object (struct value *v);
 PyObject *type_to_type_object (struct type *);
-PyObject *objfile_to_objfile_object (struct objfile *);
 
+PyObject *pspace_to_pspace_object (struct program_space *);
+PyObject *pspy_get_printers (PyObject *, void *);
+
+PyObject *objfile_to_objfile_object (struct objfile *);
 PyObject *objfpy_get_printers (PyObject *, void *);
 
 struct block *block_object_to_block (PyObject *obj);
@@ -112,6 +116,7 @@ void gdbpy_initialize_symtabs (void);
 void gdbpy_initialize_blocks (void);
 void gdbpy_initialize_types (void);
 void gdbpy_initialize_functions (void);
+void gdbpy_initialize_pspace (void);
 void gdbpy_initialize_objfile (void);
 void gdbpy_initialize_breakpoints (void);
 void gdbpy_initialize_lazy_string (void);
index b21ea99756b7cb520f4f387a8de6af2ede97c6b7..935715a3fa87336385f94b90a539c15e15a32968 100644 (file)
@@ -23,6 +23,7 @@
 #include "ui-out.h"
 #include "cli/cli-script.h"
 #include "gdbcmd.h"
+#include "progspace.h"
 #include "objfiles.h"
 #include "observer.h"
 #include "value.h"
@@ -417,6 +418,47 @@ gdbpy_print_stack (void)
 
 \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.  */
@@ -512,6 +554,7 @@ gdbpy_get_current_objfile (PyObject *unused1, PyObject *unused2)
 }
 
 /* Return a sequence holding all the Objfiles.  */
+
 static PyObject *
 gdbpy_objfiles (PyObject *unused1, PyObject *unused2)
 {
@@ -668,6 +711,7 @@ Enables or disables auto-loading of Python code when an object is opened."),
   gdbpy_initialize_blocks ();
   gdbpy_initialize_functions ();
   gdbpy_initialize_types ();
+  gdbpy_initialize_pspace ();
   gdbpy_initialize_objfile ();
   gdbpy_initialize_breakpoints ();
   gdbpy_initialize_lazy_string ();
@@ -734,6 +778,11 @@ static PyMethodDef GdbMethods[] =
   { "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,
index 9b870b5e03459e0bc364eafc60bb03ec078bcbda..142e0ae01ff854614d7a2cd9eca11f7be868d7a3 100644 (file)
@@ -1,5 +1,8 @@
 2010-04-15  Doug Evans  <dje@google.com>
 
+       * gdb.python/py-progspace.c: New file.
+       * gdb.python/py-progspace.exp: New file.
+
        * gdb.base/source-test.gdb: New file.
        * gdb.base/source.exp: Add tests for "source -s".
 
diff --git a/gdb/testsuite/gdb.python/py-progspace.c b/gdb/testsuite/gdb.python/py-progspace.c
new file mode 100644 (file)
index 0000000..898d353
--- /dev/null
@@ -0,0 +1,22 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2010 Free Software Foundation, Inc.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+int
+main ()
+{
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.python/py-progspace.exp b/gdb/testsuite/gdb.python/py-progspace.exp
new file mode 100644 (file)
index 0000000..28d67ad
--- /dev/null
@@ -0,0 +1,47 @@
+# Copyright (C) 2010 Free Software Foundation, Inc.
+
+# 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 <http://www.gnu.org/licenses/>.
+
+# This file is part of the GDB testsuite.  It tests the program space
+# support in Python.
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+set testfile "py-progspace"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    untested "Couldn't compile ${srcfile}"
+    return -1
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+# Skip all tests if Python scripting is not enabled.
+if { [skip_python_tests] } { continue }
+
+gdb_test "python print gdb.current_progspace().filename" "None" \
+  "current progspace filename (None)"
+gdb_test "python print gdb.progspaces()" "\\\[<gdb.Progspace object at $hex>\\\]"
+
+gdb_load ${binfile}
+
+gdb_test "python print gdb.current_progspace().filename" "py-progspace" \
+  "current progspace filename (py-progspace)"