]> Git Repo - binutils.git/blob - gdb/python/py-progspace.c
910c6a3fcb32a65c394f5a08d016fe328f3b8fc4
[binutils.git] / gdb / python / py-progspace.c
1 /* Python interface to program spaces.
2
3    Copyright (C) 2010-2013 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 \f
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 \f
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 \f
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 };
This page took 0.0363 seconds and 2 git commands to generate.