GDB (API)
/home/stan/gdb/src/gdb/python/py-progspace.c
Go to the documentation of this file.
00001 /* Python interface to program spaces.
00002 
00003    Copyright (C) 2010-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #include "defs.h"
00021 #include "python-internal.h"
00022 #include "charset.h"
00023 #include "progspace.h"
00024 #include "objfiles.h"
00025 #include "language.h"
00026 #include "arch-utils.h"
00027 
00028 typedef struct
00029 {
00030   PyObject_HEAD
00031 
00032   /* The corresponding pspace.  */
00033   struct program_space *pspace;
00034 
00035   /* The pretty-printer list of functions.  */
00036   PyObject *printers;
00037 
00038   /* The frame filter list of functions.  */
00039   PyObject *frame_filters;
00040   /* The type-printer list.  */
00041   PyObject *type_printers;
00042 } pspace_object;
00043 
00044 static PyTypeObject pspace_object_type
00045     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("pspace_object");
00046 
00047 static const struct program_space_data *pspy_pspace_data_key;
00048 
00049 
00050 
00051 /* An Objfile method which returns the objfile's file name, or None.  */
00052 
00053 static PyObject *
00054 pspy_get_filename (PyObject *self, void *closure)
00055 {
00056   pspace_object *obj = (pspace_object *) self;
00057 
00058   if (obj->pspace)
00059     {
00060       struct objfile *objfile = obj->pspace->symfile_object_file;
00061 
00062       if (objfile)
00063         return PyString_Decode (objfile_name (objfile),
00064                                 strlen (objfile_name (objfile)),
00065                                 host_charset (), NULL);
00066     }
00067   Py_RETURN_NONE;
00068 }
00069 
00070 static void
00071 pspy_dealloc (PyObject *self)
00072 {
00073   pspace_object *ps_self = (pspace_object *) self;
00074 
00075   Py_XDECREF (ps_self->printers);
00076   Py_XDECREF (ps_self->frame_filters);
00077   Py_XDECREF (ps_self->type_printers);
00078   Py_TYPE (self)->tp_free (self);
00079 }
00080 
00081 static PyObject *
00082 pspy_new (PyTypeObject *type, PyObject *args, PyObject *keywords)
00083 {
00084   pspace_object *self = (pspace_object *) type->tp_alloc (type, 0);
00085 
00086   if (self)
00087     {
00088       self->pspace = NULL;
00089 
00090       self->printers = PyList_New (0);
00091       if (!self->printers)
00092         {
00093           Py_DECREF (self);
00094           return NULL;
00095         }
00096 
00097       self->frame_filters = PyDict_New ();
00098       if (!self->frame_filters)
00099         {
00100           Py_DECREF (self);
00101           return NULL;
00102         }
00103 
00104       self->type_printers = PyList_New (0);
00105       if (!self->type_printers)
00106         {
00107           Py_DECREF (self);
00108           return NULL;
00109         }
00110     }
00111   return (PyObject *) self;
00112 }
00113 
00114 PyObject *
00115 pspy_get_printers (PyObject *o, void *ignore)
00116 {
00117   pspace_object *self = (pspace_object *) o;
00118 
00119   Py_INCREF (self->printers);
00120   return self->printers;
00121 }
00122 
00123 static int
00124 pspy_set_printers (PyObject *o, PyObject *value, void *ignore)
00125 {
00126   PyObject *tmp;
00127   pspace_object *self = (pspace_object *) o;
00128 
00129   if (! value)
00130     {
00131       PyErr_SetString (PyExc_TypeError,
00132                        "cannot delete the pretty_printers attribute");
00133       return -1;
00134     }
00135 
00136   if (! PyList_Check (value))
00137     {
00138       PyErr_SetString (PyExc_TypeError,
00139                        "the pretty_printers attribute must be a list");
00140       return -1;
00141     }
00142 
00143   /* Take care in case the LHS and RHS are related somehow.  */
00144   tmp = self->printers;
00145   Py_INCREF (value);
00146   self->printers = value;
00147   Py_XDECREF (tmp);
00148 
00149   return 0;
00150 }
00151 
00152 /* Return the Python dictionary attribute containing frame filters for
00153    this program space.  */
00154 PyObject *
00155 pspy_get_frame_filters (PyObject *o, void *ignore)
00156 {
00157   pspace_object *self = (pspace_object *) o;
00158 
00159   Py_INCREF (self->frame_filters);
00160   return self->frame_filters;
00161 }
00162 
00163 /* Set this object file's frame filters dictionary to FILTERS.  */
00164 static int
00165 pspy_set_frame_filters (PyObject *o, PyObject *frame, void *ignore)
00166 {
00167   PyObject *tmp;
00168   pspace_object *self = (pspace_object *) o;
00169 
00170   if (! frame)
00171     {
00172       PyErr_SetString (PyExc_TypeError,
00173                        "cannot delete the frame filter attribute");
00174       return -1;
00175     }
00176 
00177   if (! PyDict_Check (frame))
00178     {
00179       PyErr_SetString (PyExc_TypeError,
00180                        "the frame filter attribute must be a dictionary");
00181       return -1;
00182     }
00183 
00184   /* Take care in case the LHS and RHS are related somehow.  */
00185   tmp = self->frame_filters;
00186   Py_INCREF (frame);
00187   self->frame_filters = frame;
00188   Py_XDECREF (tmp);
00189 
00190   return 0;
00191 }
00192 
00193 /* Get the 'type_printers' attribute.  */
00194 
00195 static PyObject *
00196 pspy_get_type_printers (PyObject *o, void *ignore)
00197 {
00198   pspace_object *self = (pspace_object *) o;
00199 
00200   Py_INCREF (self->type_printers);
00201   return self->type_printers;
00202 }
00203 
00204 /* Set the 'type_printers' attribute.  */
00205 
00206 static int
00207 pspy_set_type_printers (PyObject *o, PyObject *value, void *ignore)
00208 {
00209   PyObject *tmp;
00210   pspace_object *self = (pspace_object *) o;
00211 
00212   if (! value)
00213     {
00214       PyErr_SetString (PyExc_TypeError,
00215                        "cannot delete the type_printers attribute");
00216       return -1;
00217     }
00218 
00219   if (! PyList_Check (value))
00220     {
00221       PyErr_SetString (PyExc_TypeError,
00222                        "the type_printers attribute must be a list");
00223       return -1;
00224     }
00225 
00226   /* Take care in case the LHS and RHS are related somehow.  */
00227   tmp = self->type_printers;
00228   Py_INCREF (value);
00229   self->type_printers = value;
00230   Py_XDECREF (tmp);
00231 
00232   return 0;
00233 }
00234 
00235 
00236 
00237 /* Clear the PSPACE pointer in a Pspace object and remove the reference.  */
00238 
00239 static void
00240 py_free_pspace (struct program_space *pspace, void *datum)
00241 {
00242   struct cleanup *cleanup;
00243   pspace_object *object = datum;
00244   struct gdbarch *arch = get_current_arch ();
00245 
00246   cleanup = ensure_python_env (arch, current_language);
00247   object->pspace = NULL;
00248   Py_DECREF ((PyObject *) object);
00249   do_cleanups (cleanup);
00250 }
00251 
00252 /* Return a borrowed reference to the Python object of type Pspace
00253    representing PSPACE.  If the object has already been created,
00254    return it.  Otherwise, create it.  Return NULL and set the Python
00255    error on failure.  */
00256 
00257 PyObject *
00258 pspace_to_pspace_object (struct program_space *pspace)
00259 {
00260   pspace_object *object;
00261 
00262   object = program_space_data (pspace, pspy_pspace_data_key);
00263   if (!object)
00264     {
00265       object = PyObject_New (pspace_object, &pspace_object_type);
00266       if (object)
00267         {
00268           object->pspace = pspace;
00269 
00270           object->printers = PyList_New (0);
00271           if (!object->printers)
00272             {
00273               Py_DECREF (object);
00274               return NULL;
00275             }
00276 
00277           object->frame_filters = PyDict_New ();
00278           if (!object->frame_filters)
00279             {
00280               Py_DECREF (object);
00281               return NULL;
00282             }
00283 
00284           object->type_printers = PyList_New (0);
00285           if (!object->type_printers)
00286             {
00287               Py_DECREF (object);
00288               return NULL;
00289             }
00290 
00291           set_program_space_data (pspace, pspy_pspace_data_key, object);
00292         }
00293     }
00294 
00295   return (PyObject *) object;
00296 }
00297 
00298 int
00299 gdbpy_initialize_pspace (void)
00300 {
00301   pspy_pspace_data_key
00302     = register_program_space_data_with_cleanup (NULL, py_free_pspace);
00303 
00304   if (PyType_Ready (&pspace_object_type) < 0)
00305     return -1;
00306 
00307   return gdb_pymodule_addobject (gdb_module, "Progspace",
00308                                  (PyObject *) &pspace_object_type);
00309 }
00310 
00311 
00312 
00313 static PyGetSetDef pspace_getset[] =
00314 {
00315   { "filename", pspy_get_filename, NULL,
00316     "The progspace's main filename, or None.", NULL },
00317   { "pretty_printers", pspy_get_printers, pspy_set_printers,
00318     "Pretty printers.", NULL },
00319   { "frame_filters", pspy_get_frame_filters, pspy_set_frame_filters,
00320     "Frame filters.", NULL },
00321   { "type_printers", pspy_get_type_printers, pspy_set_type_printers,
00322     "Type printers.", NULL },
00323   { NULL }
00324 };
00325 
00326 static PyTypeObject pspace_object_type =
00327 {
00328   PyVarObject_HEAD_INIT (NULL, 0)
00329   "gdb.Progspace",                /*tp_name*/
00330   sizeof (pspace_object),         /*tp_basicsize*/
00331   0,                              /*tp_itemsize*/
00332   pspy_dealloc,                   /*tp_dealloc*/
00333   0,                              /*tp_print*/
00334   0,                              /*tp_getattr*/
00335   0,                              /*tp_setattr*/
00336   0,                              /*tp_compare*/
00337   0,                              /*tp_repr*/
00338   0,                              /*tp_as_number*/
00339   0,                              /*tp_as_sequence*/
00340   0,                              /*tp_as_mapping*/
00341   0,                              /*tp_hash */
00342   0,                              /*tp_call*/
00343   0,                              /*tp_str*/
00344   0,                              /*tp_getattro*/
00345   0,                              /*tp_setattro*/
00346   0,                              /*tp_as_buffer*/
00347   Py_TPFLAGS_DEFAULT,             /*tp_flags*/
00348   "GDB progspace object",         /* tp_doc */
00349   0,                              /* tp_traverse */
00350   0,                              /* tp_clear */
00351   0,                              /* tp_richcompare */
00352   0,                              /* tp_weaklistoffset */
00353   0,                              /* tp_iter */
00354   0,                              /* tp_iternext */
00355   0,                              /* tp_methods */
00356   0,                              /* tp_members */
00357   pspace_getset,                  /* tp_getset */
00358   0,                              /* tp_base */
00359   0,                              /* tp_dict */
00360   0,                              /* tp_descr_get */
00361   0,                              /* tp_descr_set */
00362   0,                              /* tp_dictoffset */
00363   0,                              /* tp_init */
00364   0,                              /* tp_alloc */
00365   pspy_new,                       /* tp_new */
00366 };
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines