Add ability to add attributes to gdb.Objfile and gdb.Progspace objects.
[external/binutils.git] / gdb / python / py-objfile.c
1 /* Python interface to objfiles.
2
3    Copyright (C) 2008-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 "objfiles.h"
24 #include "language.h"
25
26 typedef struct
27 {
28   PyObject_HEAD
29
30   /* The corresponding objfile.  */
31   struct objfile *objfile;
32
33   /* Dictionary holding user-added attributes.
34      This is the __dict__ attribute of the object.  */
35   PyObject *dict;
36
37   /* The pretty-printer list of functions.  */
38   PyObject *printers;
39
40   /* The frame filter list of functions.  */
41   PyObject *frame_filters;
42   /* The type-printer list.  */
43   PyObject *type_printers;
44
45   /* The debug method matcher list.  */
46   PyObject *xmethods;
47 } objfile_object;
48
49 static PyTypeObject objfile_object_type
50     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("objfile_object");
51
52 static const struct objfile_data *objfpy_objfile_data_key;
53
54 \f
55
56 /* An Objfile method which returns the objfile's file name, or None.  */
57 static PyObject *
58 objfpy_get_filename (PyObject *self, void *closure)
59 {
60   objfile_object *obj = (objfile_object *) self;
61
62   if (obj->objfile)
63     return PyString_Decode (objfile_name (obj->objfile),
64                             strlen (objfile_name (obj->objfile)),
65                             host_charset (), NULL);
66   Py_RETURN_NONE;
67 }
68
69 /* An Objfile method which returns the objfile's progspace, or None.  */
70
71 static PyObject *
72 objfpy_get_progspace (PyObject *self, void *closure)
73 {
74   objfile_object *obj = (objfile_object *) self;
75
76   if (obj->objfile)
77     {
78       PyObject *pspace =  pspace_to_pspace_object (obj->objfile->pspace);
79
80       Py_XINCREF (pspace);
81       return pspace;
82     }
83
84   Py_RETURN_NONE;
85 }
86
87 static void
88 objfpy_dealloc (PyObject *o)
89 {
90   objfile_object *self = (objfile_object *) o;
91
92   Py_XDECREF (self->dict);
93   Py_XDECREF (self->printers);
94   Py_XDECREF (self->frame_filters);
95   Py_XDECREF (self->type_printers);
96   Py_XDECREF (self->xmethods);
97   Py_TYPE (self)->tp_free (self);
98 }
99
100 /* Initialize an objfile_object.
101    The result is a boolean indicating success.  */
102
103 static int
104 objfpy_initialize (objfile_object *self)
105 {
106   self->objfile = NULL;
107   self->dict = NULL;
108
109   self->printers = PyList_New (0);
110   if (self->printers == NULL)
111     return 0;
112
113   self->frame_filters = PyDict_New ();
114   if (self->frame_filters == NULL)
115     return 0;
116
117   self->type_printers = PyList_New (0);
118   if (self->type_printers == NULL)
119     return 0;
120
121   self->xmethods = PyList_New (0);
122   if (self->xmethods == NULL)
123     return 0;
124
125   return 1;
126 }
127
128 static PyObject *
129 objfpy_new (PyTypeObject *type, PyObject *args, PyObject *keywords)
130 {
131   objfile_object *self = (objfile_object *) type->tp_alloc (type, 0);
132
133   if (self)
134     {
135       if (!objfpy_initialize (self))
136         {
137           Py_DECREF (self);
138           return NULL;
139         }
140     }
141
142   return (PyObject *) self;
143 }
144
145 PyObject *
146 objfpy_get_printers (PyObject *o, void *ignore)
147 {
148   objfile_object *self = (objfile_object *) o;
149
150   Py_INCREF (self->printers);
151   return self->printers;
152 }
153
154 static int
155 objfpy_set_printers (PyObject *o, PyObject *value, void *ignore)
156 {
157   PyObject *tmp;
158   objfile_object *self = (objfile_object *) o;
159
160   if (! value)
161     {
162       PyErr_SetString (PyExc_TypeError,
163                        _("Cannot delete the pretty_printers attribute."));
164       return -1;
165     }
166
167   if (! PyList_Check (value))
168     {
169       PyErr_SetString (PyExc_TypeError,
170                        _("The pretty_printers attribute must be a list."));
171       return -1;
172     }
173
174   /* Take care in case the LHS and RHS are related somehow.  */
175   tmp = self->printers;
176   Py_INCREF (value);
177   self->printers = value;
178   Py_XDECREF (tmp);
179
180   return 0;
181 }
182
183 /* Return the Python dictionary attribute containing frame filters for
184    this object file.  */
185 PyObject *
186 objfpy_get_frame_filters (PyObject *o, void *ignore)
187 {
188   objfile_object *self = (objfile_object *) o;
189
190   Py_INCREF (self->frame_filters);
191   return self->frame_filters;
192 }
193
194 /* Set this object file's frame filters dictionary to FILTERS.  */
195 static int
196 objfpy_set_frame_filters (PyObject *o, PyObject *filters, void *ignore)
197 {
198   PyObject *tmp;
199   objfile_object *self = (objfile_object *) o;
200
201   if (! filters)
202     {
203       PyErr_SetString (PyExc_TypeError,
204                        _("Cannot delete the frame filters attribute."));
205       return -1;
206     }
207
208   if (! PyDict_Check (filters))
209     {
210       PyErr_SetString (PyExc_TypeError,
211                        _("The frame_filters attribute must be a dictionary."));
212       return -1;
213     }
214
215   /* Take care in case the LHS and RHS are related somehow.  */
216   tmp = self->frame_filters;
217   Py_INCREF (filters);
218   self->frame_filters = filters;
219   Py_XDECREF (tmp);
220
221   return 0;
222 }
223
224 /* Get the 'type_printers' attribute.  */
225
226 static PyObject *
227 objfpy_get_type_printers (PyObject *o, void *ignore)
228 {
229   objfile_object *self = (objfile_object *) o;
230
231   Py_INCREF (self->type_printers);
232   return self->type_printers;
233 }
234
235 /* Get the 'xmethods' attribute.  */
236
237 PyObject *
238 objfpy_get_xmethods (PyObject *o, void *ignore)
239 {
240   objfile_object *self = (objfile_object *) o;
241
242   Py_INCREF (self->xmethods);
243   return self->xmethods;
244 }
245
246 /* Set the 'type_printers' attribute.  */
247
248 static int
249 objfpy_set_type_printers (PyObject *o, PyObject *value, void *ignore)
250 {
251   PyObject *tmp;
252   objfile_object *self = (objfile_object *) o;
253
254   if (! value)
255     {
256       PyErr_SetString (PyExc_TypeError,
257                        _("Cannot delete the type_printers attribute."));
258       return -1;
259     }
260
261   if (! PyList_Check (value))
262     {
263       PyErr_SetString (PyExc_TypeError,
264                        _("The type_printers attribute must be a list."));
265       return -1;
266     }
267
268   /* Take care in case the LHS and RHS are related somehow.  */
269   tmp = self->type_printers;
270   Py_INCREF (value);
271   self->type_printers = value;
272   Py_XDECREF (tmp);
273
274   return 0;
275 }
276
277 /* Implementation of gdb.Objfile.is_valid (self) -> Boolean.
278    Returns True if this object file still exists in GDB.  */
279
280 static PyObject *
281 objfpy_is_valid (PyObject *self, PyObject *args)
282 {
283   objfile_object *obj = (objfile_object *) self;
284
285   if (! obj->objfile)
286     Py_RETURN_FALSE;
287
288   Py_RETURN_TRUE;
289 }
290
291 \f
292
293 /* Clear the OBJFILE pointer in an Objfile object and remove the
294    reference.  */
295 static void
296 py_free_objfile (struct objfile *objfile, void *datum)
297 {
298   struct cleanup *cleanup;
299   objfile_object *object = datum;
300
301   cleanup = ensure_python_env (get_objfile_arch (objfile), current_language);
302   object->objfile = NULL;
303   Py_DECREF ((PyObject *) object);
304   do_cleanups (cleanup);
305 }
306
307 /* Return a borrowed reference to the Python object of type Objfile
308    representing OBJFILE.  If the object has already been created,
309    return it.  Otherwise, create it.  Return NULL and set the Python
310    error on failure.  */
311
312 PyObject *
313 objfile_to_objfile_object (struct objfile *objfile)
314 {
315   objfile_object *object;
316
317   object = objfile_data (objfile, objfpy_objfile_data_key);
318   if (!object)
319     {
320       object = PyObject_New (objfile_object, &objfile_object_type);
321       if (object)
322         {
323           if (!objfpy_initialize (object))
324             {
325               Py_DECREF (object);
326               return NULL;
327             }
328
329           object->objfile = objfile;
330           set_objfile_data (objfile, objfpy_objfile_data_key, object);
331         }
332     }
333
334   return (PyObject *) object;
335 }
336
337 int
338 gdbpy_initialize_objfile (void)
339 {
340   objfpy_objfile_data_key
341     = register_objfile_data_with_cleanup (NULL, py_free_objfile);
342
343   if (PyType_Ready (&objfile_object_type) < 0)
344     return -1;
345
346   return gdb_pymodule_addobject (gdb_module, "Objfile",
347                                  (PyObject *) &objfile_object_type);
348 }
349
350 \f
351
352 static PyMethodDef objfile_object_methods[] =
353 {
354   { "is_valid", objfpy_is_valid, METH_NOARGS,
355     "is_valid () -> Boolean.\n\
356 Return true if this object file is valid, false if not." },
357
358   { NULL }
359 };
360
361 static PyGetSetDef objfile_getset[] =
362 {
363   { "__dict__", gdb_py_generic_dict, NULL,
364     "The __dict__ for this objfile.", &objfile_object_type },
365   { "filename", objfpy_get_filename, NULL,
366     "The objfile's filename, or None.", NULL },
367   { "progspace", objfpy_get_progspace, NULL,
368     "The objfile's progspace, or None.", NULL },
369   { "pretty_printers", objfpy_get_printers, objfpy_set_printers,
370     "Pretty printers.", NULL },
371   { "frame_filters", objfpy_get_frame_filters,
372     objfpy_set_frame_filters, "Frame Filters.", NULL },
373   { "type_printers", objfpy_get_type_printers, objfpy_set_type_printers,
374     "Type printers.", NULL },
375   { "xmethods", objfpy_get_xmethods, NULL,
376     "Debug methods.", NULL },
377   { NULL }
378 };
379
380 static PyTypeObject objfile_object_type =
381 {
382   PyVarObject_HEAD_INIT (NULL, 0)
383   "gdb.Objfile",                  /*tp_name*/
384   sizeof (objfile_object),        /*tp_basicsize*/
385   0,                              /*tp_itemsize*/
386   objfpy_dealloc,                 /*tp_dealloc*/
387   0,                              /*tp_print*/
388   0,                              /*tp_getattr*/
389   0,                              /*tp_setattr*/
390   0,                              /*tp_compare*/
391   0,                              /*tp_repr*/
392   0,                              /*tp_as_number*/
393   0,                              /*tp_as_sequence*/
394   0,                              /*tp_as_mapping*/
395   0,                              /*tp_hash */
396   0,                              /*tp_call*/
397   0,                              /*tp_str*/
398   0,                              /*tp_getattro*/
399   0,                              /*tp_setattro*/
400   0,                              /*tp_as_buffer*/
401   Py_TPFLAGS_DEFAULT,             /*tp_flags*/
402   "GDB objfile object",           /* tp_doc */
403   0,                              /* tp_traverse */
404   0,                              /* tp_clear */
405   0,                              /* tp_richcompare */
406   0,                              /* tp_weaklistoffset */
407   0,                              /* tp_iter */
408   0,                              /* tp_iternext */
409   objfile_object_methods,         /* tp_methods */
410   0,                              /* tp_members */
411   objfile_getset,                 /* tp_getset */
412   0,                              /* tp_base */
413   0,                              /* tp_dict */
414   0,                              /* tp_descr_get */
415   0,                              /* tp_descr_set */
416   offsetof (objfile_object, dict), /* tp_dictoffset */
417   0,                              /* tp_init */
418   0,                              /* tp_alloc */
419   objfpy_new,                     /* tp_new */
420 };