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