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