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 type-printer list.  */
39   PyObject *type_printers;
40 } pspace_object;
41 
42 static PyTypeObject pspace_object_type;
43 
44 static const struct program_space_data *pspy_pspace_data_key;
45 
46 
47 
48 /* An Objfile method which returns the objfile's file name, or None.  */
49 
50 static PyObject *
51 pspy_get_filename (PyObject *self, void *closure)
52 {
53   pspace_object *obj = (pspace_object *) self;
54 
55   if (obj->pspace)
56     {
57       struct objfile *objfile = obj->pspace->symfile_object_file;
58 
59       if (objfile)
60 	return PyString_Decode (objfile->name, strlen (objfile->name),
61 				host_charset (), NULL);
62     }
63   Py_RETURN_NONE;
64 }
65 
66 static void
67 pspy_dealloc (PyObject *self)
68 {
69   pspace_object *ps_self = (pspace_object *) self;
70 
71   Py_XDECREF (ps_self->printers);
72   Py_XDECREF (ps_self->type_printers);
73   Py_TYPE (self)->tp_free (self);
74 }
75 
76 static PyObject *
77 pspy_new (PyTypeObject *type, PyObject *args, PyObject *keywords)
78 {
79   pspace_object *self = (pspace_object *) type->tp_alloc (type, 0);
80 
81   if (self)
82     {
83       self->pspace = NULL;
84 
85       self->printers = PyList_New (0);
86       if (!self->printers)
87 	{
88 	  Py_DECREF (self);
89 	  return NULL;
90 	}
91 
92       self->type_printers = PyList_New (0);
93       if (!self->type_printers)
94 	{
95 	  Py_DECREF (self);
96 	  return NULL;
97 	}
98     }
99   return (PyObject *) self;
100 }
101 
102 PyObject *
103 pspy_get_printers (PyObject *o, void *ignore)
104 {
105   pspace_object *self = (pspace_object *) o;
106 
107   Py_INCREF (self->printers);
108   return self->printers;
109 }
110 
111 static int
112 pspy_set_printers (PyObject *o, PyObject *value, void *ignore)
113 {
114   PyObject *tmp;
115   pspace_object *self = (pspace_object *) o;
116 
117   if (! value)
118     {
119       PyErr_SetString (PyExc_TypeError,
120 		       "cannot delete the pretty_printers attribute");
121       return -1;
122     }
123 
124   if (! PyList_Check (value))
125     {
126       PyErr_SetString (PyExc_TypeError,
127 		       "the pretty_printers attribute must be a list");
128       return -1;
129     }
130 
131   /* Take care in case the LHS and RHS are related somehow.  */
132   tmp = self->printers;
133   Py_INCREF (value);
134   self->printers = value;
135   Py_XDECREF (tmp);
136 
137   return 0;
138 }
139 
140 /* Get the 'type_printers' attribute.  */
141 
142 static PyObject *
143 pspy_get_type_printers (PyObject *o, void *ignore)
144 {
145   pspace_object *self = (pspace_object *) o;
146 
147   Py_INCREF (self->type_printers);
148   return self->type_printers;
149 }
150 
151 /* Set the 'type_printers' attribute.  */
152 
153 static int
154 pspy_set_type_printers (PyObject *o, PyObject *value, void *ignore)
155 {
156   PyObject *tmp;
157   pspace_object *self = (pspace_object *) o;
158 
159   if (! value)
160     {
161       PyErr_SetString (PyExc_TypeError,
162 		       "cannot delete the type_printers attribute");
163       return -1;
164     }
165 
166   if (! PyList_Check (value))
167     {
168       PyErr_SetString (PyExc_TypeError,
169 		       "the type_printers attribute must be a list");
170       return -1;
171     }
172 
173   /* Take care in case the LHS and RHS are related somehow.  */
174   tmp = self->type_printers;
175   Py_INCREF (value);
176   self->type_printers = value;
177   Py_XDECREF (tmp);
178 
179   return 0;
180 }
181 
182 
183 
184 /* Clear the PSPACE pointer in a Pspace object and remove the reference.  */
185 
186 static void
187 py_free_pspace (struct program_space *pspace, void *datum)
188 {
189   struct cleanup *cleanup;
190   pspace_object *object = datum;
191   struct gdbarch *arch = get_current_arch ();
192 
193   cleanup = ensure_python_env (arch, current_language);
194   object->pspace = NULL;
195   Py_DECREF ((PyObject *) object);
196   do_cleanups (cleanup);
197 }
198 
199 /* Return a borrowed reference to the Python object of type Pspace
200    representing PSPACE.  If the object has already been created,
201    return it.  Otherwise, create it.  Return NULL and set the Python
202    error on failure.  */
203 
204 PyObject *
205 pspace_to_pspace_object (struct program_space *pspace)
206 {
207   pspace_object *object;
208 
209   object = program_space_data (pspace, pspy_pspace_data_key);
210   if (!object)
211     {
212       object = PyObject_New (pspace_object, &pspace_object_type);
213       if (object)
214 	{
215 	  object->pspace = pspace;
216 
217 	  object->printers = PyList_New (0);
218 	  if (!object->printers)
219 	    {
220 	      Py_DECREF (object);
221 	      return NULL;
222 	    }
223 
224 	  object->type_printers = PyList_New (0);
225 	  if (!object->type_printers)
226 	    {
227 	      Py_DECREF (object);
228 	      return NULL;
229 	    }
230 
231 	  set_program_space_data (pspace, pspy_pspace_data_key, object);
232 	}
233     }
234 
235   return (PyObject *) object;
236 }
237 
238 void
239 gdbpy_initialize_pspace (void)
240 {
241   pspy_pspace_data_key
242     = register_program_space_data_with_cleanup (NULL, py_free_pspace);
243 
244   if (PyType_Ready (&pspace_object_type) < 0)
245     return;
246 
247   Py_INCREF (&pspace_object_type);
248   PyModule_AddObject (gdb_module, "Progspace",
249 		      (PyObject *) &pspace_object_type);
250 }
251 
252 
253 
254 static PyGetSetDef pspace_getset[] =
255 {
256   { "filename", pspy_get_filename, NULL,
257     "The progspace's main filename, or None.", NULL },
258   { "pretty_printers", pspy_get_printers, pspy_set_printers,
259     "Pretty printers.", NULL },
260   { "type_printers", pspy_get_type_printers, pspy_set_type_printers,
261     "Type printers.", NULL },
262   { NULL }
263 };
264 
265 static PyTypeObject pspace_object_type =
266 {
267   PyVarObject_HEAD_INIT (NULL, 0)
268   "gdb.Progspace",		  /*tp_name*/
269   sizeof (pspace_object),	  /*tp_basicsize*/
270   0,				  /*tp_itemsize*/
271   pspy_dealloc,			  /*tp_dealloc*/
272   0,				  /*tp_print*/
273   0,				  /*tp_getattr*/
274   0,				  /*tp_setattr*/
275   0,				  /*tp_compare*/
276   0,				  /*tp_repr*/
277   0,				  /*tp_as_number*/
278   0,				  /*tp_as_sequence*/
279   0,				  /*tp_as_mapping*/
280   0,				  /*tp_hash */
281   0,				  /*tp_call*/
282   0,				  /*tp_str*/
283   0,				  /*tp_getattro*/
284   0,				  /*tp_setattro*/
285   0,				  /*tp_as_buffer*/
286   Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
287   "GDB progspace object",	  /* tp_doc */
288   0,				  /* tp_traverse */
289   0,				  /* tp_clear */
290   0,				  /* tp_richcompare */
291   0,				  /* tp_weaklistoffset */
292   0,				  /* tp_iter */
293   0,				  /* tp_iternext */
294   0,				  /* tp_methods */
295   0,				  /* tp_members */
296   pspace_getset,		  /* tp_getset */
297   0,				  /* tp_base */
298   0,				  /* tp_dict */
299   0,				  /* tp_descr_get */
300   0,				  /* tp_descr_set */
301   0,				  /* tp_dictoffset */
302   0,				  /* tp_init */
303   0,				  /* tp_alloc */
304   pspy_new,			  /* tp_new */
305 };
306