xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/python/py-progspace.c (revision 0ab5b340411a90c5db2463a3bd38d565fa784c5c)
1 /* Python interface to program spaces.
2 
3    Copyright (C) 2010-2014 Free Software Foundation, Inc.
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 #include "defs.h"
21 #include "python-internal.h"
22 #include "charset.h"
23 #include "progspace.h"
24 #include "objfiles.h"
25 #include "language.h"
26 #include "arch-utils.h"
27 
28 typedef struct
29 {
30   PyObject_HEAD
31 
32   /* The corresponding pspace.  */
33   struct program_space *pspace;
34 
35   /* The pretty-printer list of functions.  */
36   PyObject *printers;
37 
38   /* The frame filter list of functions.  */
39   PyObject *frame_filters;
40   /* The type-printer list.  */
41   PyObject *type_printers;
42 } pspace_object;
43 
44 static PyTypeObject pspace_object_type
45     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("pspace_object");
46 
47 static const struct program_space_data *pspy_pspace_data_key;
48 
49 
50 
51 /* An Objfile method which returns the objfile's file name, or None.  */
52 
53 static PyObject *
54 pspy_get_filename (PyObject *self, void *closure)
55 {
56   pspace_object *obj = (pspace_object *) self;
57 
58   if (obj->pspace)
59     {
60       struct objfile *objfile = obj->pspace->symfile_object_file;
61 
62       if (objfile)
63 	return PyString_Decode (objfile_name (objfile),
64 				strlen (objfile_name (objfile)),
65 				host_charset (), NULL);
66     }
67   Py_RETURN_NONE;
68 }
69 
70 static void
71 pspy_dealloc (PyObject *self)
72 {
73   pspace_object *ps_self = (pspace_object *) self;
74 
75   Py_XDECREF (ps_self->printers);
76   Py_XDECREF (ps_self->frame_filters);
77   Py_XDECREF (ps_self->type_printers);
78   Py_TYPE (self)->tp_free (self);
79 }
80 
81 static PyObject *
82 pspy_new (PyTypeObject *type, PyObject *args, PyObject *keywords)
83 {
84   pspace_object *self = (pspace_object *) type->tp_alloc (type, 0);
85 
86   if (self)
87     {
88       self->pspace = NULL;
89 
90       self->printers = PyList_New (0);
91       if (!self->printers)
92 	{
93 	  Py_DECREF (self);
94 	  return NULL;
95 	}
96 
97       self->frame_filters = PyDict_New ();
98       if (!self->frame_filters)
99 	{
100 	  Py_DECREF (self);
101 	  return NULL;
102 	}
103 
104       self->type_printers = PyList_New (0);
105       if (!self->type_printers)
106 	{
107 	  Py_DECREF (self);
108 	  return NULL;
109 	}
110     }
111   return (PyObject *) self;
112 }
113 
114 PyObject *
115 pspy_get_printers (PyObject *o, void *ignore)
116 {
117   pspace_object *self = (pspace_object *) o;
118 
119   Py_INCREF (self->printers);
120   return self->printers;
121 }
122 
123 static int
124 pspy_set_printers (PyObject *o, PyObject *value, void *ignore)
125 {
126   PyObject *tmp;
127   pspace_object *self = (pspace_object *) o;
128 
129   if (! value)
130     {
131       PyErr_SetString (PyExc_TypeError,
132 		       "cannot delete the pretty_printers attribute");
133       return -1;
134     }
135 
136   if (! PyList_Check (value))
137     {
138       PyErr_SetString (PyExc_TypeError,
139 		       "the pretty_printers attribute must be a list");
140       return -1;
141     }
142 
143   /* Take care in case the LHS and RHS are related somehow.  */
144   tmp = self->printers;
145   Py_INCREF (value);
146   self->printers = value;
147   Py_XDECREF (tmp);
148 
149   return 0;
150 }
151 
152 /* Return the Python dictionary attribute containing frame filters for
153    this program space.  */
154 PyObject *
155 pspy_get_frame_filters (PyObject *o, void *ignore)
156 {
157   pspace_object *self = (pspace_object *) o;
158 
159   Py_INCREF (self->frame_filters);
160   return self->frame_filters;
161 }
162 
163 /* Set this object file's frame filters dictionary to FILTERS.  */
164 static int
165 pspy_set_frame_filters (PyObject *o, PyObject *frame, void *ignore)
166 {
167   PyObject *tmp;
168   pspace_object *self = (pspace_object *) o;
169 
170   if (! frame)
171     {
172       PyErr_SetString (PyExc_TypeError,
173 		       "cannot delete the frame filter attribute");
174       return -1;
175     }
176 
177   if (! PyDict_Check (frame))
178     {
179       PyErr_SetString (PyExc_TypeError,
180 		       "the frame filter attribute must be a dictionary");
181       return -1;
182     }
183 
184   /* Take care in case the LHS and RHS are related somehow.  */
185   tmp = self->frame_filters;
186   Py_INCREF (frame);
187   self->frame_filters = frame;
188   Py_XDECREF (tmp);
189 
190   return 0;
191 }
192 
193 /* Get the 'type_printers' attribute.  */
194 
195 static PyObject *
196 pspy_get_type_printers (PyObject *o, void *ignore)
197 {
198   pspace_object *self = (pspace_object *) o;
199 
200   Py_INCREF (self->type_printers);
201   return self->type_printers;
202 }
203 
204 /* Set the 'type_printers' attribute.  */
205 
206 static int
207 pspy_set_type_printers (PyObject *o, PyObject *value, void *ignore)
208 {
209   PyObject *tmp;
210   pspace_object *self = (pspace_object *) o;
211 
212   if (! value)
213     {
214       PyErr_SetString (PyExc_TypeError,
215 		       "cannot delete the type_printers attribute");
216       return -1;
217     }
218 
219   if (! PyList_Check (value))
220     {
221       PyErr_SetString (PyExc_TypeError,
222 		       "the type_printers attribute must be a list");
223       return -1;
224     }
225 
226   /* Take care in case the LHS and RHS are related somehow.  */
227   tmp = self->type_printers;
228   Py_INCREF (value);
229   self->type_printers = value;
230   Py_XDECREF (tmp);
231 
232   return 0;
233 }
234 
235 
236 
237 /* Clear the PSPACE pointer in a Pspace object and remove the reference.  */
238 
239 static void
240 py_free_pspace (struct program_space *pspace, void *datum)
241 {
242   struct cleanup *cleanup;
243   pspace_object *object = datum;
244   struct gdbarch *arch = get_current_arch ();
245 
246   cleanup = ensure_python_env (arch, current_language);
247   object->pspace = NULL;
248   Py_DECREF ((PyObject *) object);
249   do_cleanups (cleanup);
250 }
251 
252 /* Return a borrowed reference to the Python object of type Pspace
253    representing PSPACE.  If the object has already been created,
254    return it.  Otherwise, create it.  Return NULL and set the Python
255    error on failure.  */
256 
257 PyObject *
258 pspace_to_pspace_object (struct program_space *pspace)
259 {
260   pspace_object *object;
261 
262   object = program_space_data (pspace, pspy_pspace_data_key);
263   if (!object)
264     {
265       object = PyObject_New (pspace_object, &pspace_object_type);
266       if (object)
267 	{
268 	  object->pspace = pspace;
269 
270 	  object->printers = PyList_New (0);
271 	  if (!object->printers)
272 	    {
273 	      Py_DECREF (object);
274 	      return NULL;
275 	    }
276 
277 	  object->frame_filters = PyDict_New ();
278 	  if (!object->frame_filters)
279 	    {
280 	      Py_DECREF (object);
281 	      return NULL;
282 	    }
283 
284 	  object->type_printers = PyList_New (0);
285 	  if (!object->type_printers)
286 	    {
287 	      Py_DECREF (object);
288 	      return NULL;
289 	    }
290 
291 	  set_program_space_data (pspace, pspy_pspace_data_key, object);
292 	}
293     }
294 
295   return (PyObject *) object;
296 }
297 
298 int
299 gdbpy_initialize_pspace (void)
300 {
301   pspy_pspace_data_key
302     = register_program_space_data_with_cleanup (NULL, py_free_pspace);
303 
304   if (PyType_Ready (&pspace_object_type) < 0)
305     return -1;
306 
307   return gdb_pymodule_addobject (gdb_module, "Progspace",
308 				 (PyObject *) &pspace_object_type);
309 }
310 
311 
312 
313 static PyGetSetDef pspace_getset[] =
314 {
315   { "filename", pspy_get_filename, NULL,
316     "The progspace's main filename, or None.", NULL },
317   { "pretty_printers", pspy_get_printers, pspy_set_printers,
318     "Pretty printers.", NULL },
319   { "frame_filters", pspy_get_frame_filters, pspy_set_frame_filters,
320     "Frame filters.", NULL },
321   { "type_printers", pspy_get_type_printers, pspy_set_type_printers,
322     "Type printers.", NULL },
323   { NULL }
324 };
325 
326 static PyTypeObject pspace_object_type =
327 {
328   PyVarObject_HEAD_INIT (NULL, 0)
329   "gdb.Progspace",		  /*tp_name*/
330   sizeof (pspace_object),	  /*tp_basicsize*/
331   0,				  /*tp_itemsize*/
332   pspy_dealloc,			  /*tp_dealloc*/
333   0,				  /*tp_print*/
334   0,				  /*tp_getattr*/
335   0,				  /*tp_setattr*/
336   0,				  /*tp_compare*/
337   0,				  /*tp_repr*/
338   0,				  /*tp_as_number*/
339   0,				  /*tp_as_sequence*/
340   0,				  /*tp_as_mapping*/
341   0,				  /*tp_hash */
342   0,				  /*tp_call*/
343   0,				  /*tp_str*/
344   0,				  /*tp_getattro*/
345   0,				  /*tp_setattro*/
346   0,				  /*tp_as_buffer*/
347   Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
348   "GDB progspace object",	  /* tp_doc */
349   0,				  /* tp_traverse */
350   0,				  /* tp_clear */
351   0,				  /* tp_richcompare */
352   0,				  /* tp_weaklistoffset */
353   0,				  /* tp_iter */
354   0,				  /* tp_iternext */
355   0,				  /* tp_methods */
356   0,				  /* tp_members */
357   pspace_getset,		  /* tp_getset */
358   0,				  /* tp_base */
359   0,				  /* tp_dict */
360   0,				  /* tp_descr_get */
361   0,				  /* tp_descr_set */
362   0,				  /* tp_dictoffset */
363   0,				  /* tp_init */
364   0,				  /* tp_alloc */
365   pspy_new,			  /* tp_new */
366 };
367