xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/python/py-function.c (revision 200d779b75dbeafa7bc01fd0f60bc61185f6967b)
1 /* Convenience functions implemented in Python.
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 
21 #include "defs.h"
22 #include "value.h"
23 #include "exceptions.h"
24 #include "python-internal.h"
25 #include "charset.h"
26 #include "gdbcmd.h"
27 #include "cli/cli-decode.h"
28 #include "completer.h"
29 #include "expression.h"
30 #include "language.h"
31 
32 static PyTypeObject fnpy_object_type
33     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("PyObject");
34 
35 
36 
37 static PyObject *
38 convert_values_to_python (int argc, struct value **argv)
39 {
40   int i;
41   PyObject *result = PyTuple_New (argc);
42 
43   if (! result)
44     return NULL;
45 
46   for (i = 0; i < argc; ++i)
47     {
48       PyObject *elt = value_to_value_object (argv[i]);
49       if (! elt)
50 	{
51 	  Py_DECREF (result);
52 	  return NULL;
53 	}
54       PyTuple_SetItem (result, i, elt);
55     }
56   return result;
57 }
58 
59 /* Call a Python function object's invoke method.  */
60 
61 static struct value *
62 fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language,
63 	   void *cookie, int argc, struct value **argv)
64 {
65   struct value *value = NULL;
66   /* 'result' must be set to NULL, this initially indicates whether
67      the function was called, or not.  */
68   PyObject *result = NULL;
69   PyObject *callable, *args;
70   struct cleanup *cleanup;
71 
72   cleanup = ensure_python_env (gdbarch, language);
73 
74   args = convert_values_to_python (argc, argv);
75   /* convert_values_to_python can return NULL on error.  If we
76      encounter this, do not call the function, but allow the Python ->
77      error code conversion below to deal with the Python exception.
78      Note, that this is different if the function simply does not
79      have arguments.  */
80 
81   if (args)
82     {
83       callable = PyObject_GetAttrString ((PyObject *) cookie, "invoke");
84       if (! callable)
85 	{
86 	  Py_DECREF (args);
87 	  error (_("No method named 'invoke' in object."));
88 	}
89 
90       result = PyObject_Call (callable, args, NULL);
91       Py_DECREF (callable);
92       Py_DECREF (args);
93     }
94 
95   if (!result)
96     {
97       PyObject *ptype, *pvalue, *ptraceback;
98       char *msg;
99 
100       PyErr_Fetch (&ptype, &pvalue, &ptraceback);
101 
102       /* Try to fetch an error message contained within ptype, pvalue.
103 	 When fetching the error message we need to make our own copy,
104 	 we no longer own ptype, pvalue after the call to PyErr_Restore.  */
105 
106       msg = gdbpy_exception_to_string (ptype, pvalue);
107       make_cleanup (xfree, msg);
108 
109       if (msg == NULL)
110 	{
111 	  /* An error occurred computing the string representation of the
112 	     error message.  This is rare, but we should inform the user.  */
113 
114 	  printf_filtered (_("An error occurred in a Python "
115 			     "convenience function\n"
116 			     "and then another occurred computing the "
117 			     "error message.\n"));
118 	  gdbpy_print_stack ();
119 	}
120 
121       /* Don't print the stack for gdb.GdbError exceptions.
122 	 It is generally used to flag user errors.
123 
124 	 We also don't want to print "Error occurred in Python command"
125 	 for user errors.  However, a missing message for gdb.GdbError
126 	 exceptions is arguably a bug, so we flag it as such.  */
127 
128       if (!PyErr_GivenExceptionMatches (ptype, gdbpy_gdberror_exc)
129 	  || msg == NULL || *msg == '\0')
130 	{
131 	  PyErr_Restore (ptype, pvalue, ptraceback);
132 	  gdbpy_print_stack ();
133 	  if (msg != NULL && *msg != '\0')
134 	    error (_("Error occurred in Python convenience function: %s"),
135 		   msg);
136 	  else
137 	    error (_("Error occurred in Python convenience function."));
138 	}
139       else
140 	{
141 	  Py_XDECREF (ptype);
142 	  Py_XDECREF (pvalue);
143 	  Py_XDECREF (ptraceback);
144 	  error ("%s", msg);
145 	}
146     }
147 
148   value = convert_value_from_python (result);
149   if (value == NULL)
150     {
151       Py_DECREF (result);
152       gdbpy_print_stack ();
153       error (_("Error while executing Python code."));
154     }
155 
156   Py_DECREF (result);
157   do_cleanups (cleanup);
158 
159   return value;
160 }
161 
162 /* Initializer for a Function object.  It takes one argument, the name
163    of the function.  */
164 
165 static int
166 fnpy_init (PyObject *self, PyObject *args, PyObject *kwds)
167 {
168   const char *name;
169   char *docstring = NULL;
170 
171   if (! PyArg_ParseTuple (args, "s", &name))
172     return -1;
173   Py_INCREF (self);
174 
175   if (PyObject_HasAttrString (self, "__doc__"))
176     {
177       PyObject *ds_obj = PyObject_GetAttrString (self, "__doc__");
178       if (ds_obj != NULL)
179 	{
180 	  if (gdbpy_is_string (ds_obj))
181 	    {
182 	      docstring = python_string_to_host_string (ds_obj);
183 	      if (docstring == NULL)
184 		{
185 		  Py_DECREF (self);
186 		  Py_DECREF (ds_obj);
187 		  return -1;
188 		}
189 	    }
190 
191 	  Py_DECREF (ds_obj);
192 	}
193     }
194   if (! docstring)
195     docstring = xstrdup (_("This function is not documented."));
196 
197   add_internal_function (name, docstring, fnpy_call, self);
198   return 0;
199 }
200 
201 /* Initialize internal function support.  */
202 
203 int
204 gdbpy_initialize_functions (void)
205 {
206   fnpy_object_type.tp_new = PyType_GenericNew;
207   if (PyType_Ready (&fnpy_object_type) < 0)
208     return -1;
209 
210   return gdb_pymodule_addobject (gdb_module, "Function",
211 				 (PyObject *) &fnpy_object_type);
212 }
213 
214 
215 
216 static PyTypeObject fnpy_object_type =
217 {
218   PyVarObject_HEAD_INIT (NULL, 0)
219   "gdb.Function",		  /*tp_name*/
220   sizeof (PyObject),		  /*tp_basicsize*/
221   0,				  /*tp_itemsize*/
222   0,				  /*tp_dealloc*/
223   0,				  /*tp_print*/
224   0,				  /*tp_getattr*/
225   0,				  /*tp_setattr*/
226   0,				  /*tp_compare*/
227   0,				  /*tp_repr*/
228   0,				  /*tp_as_number*/
229   0,				  /*tp_as_sequence*/
230   0,				  /*tp_as_mapping*/
231   0,				  /*tp_hash */
232   0,				  /*tp_call*/
233   0,				  /*tp_str*/
234   0,				  /*tp_getattro*/
235   0,				  /*tp_setattro*/
236   0,				  /*tp_as_buffer*/
237   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
238   "GDB function object",	  /* tp_doc */
239   0,				  /* tp_traverse */
240   0,				  /* tp_clear */
241   0,				  /* tp_richcompare */
242   0,				  /* tp_weaklistoffset */
243   0,				  /* tp_iter */
244   0,				  /* tp_iternext */
245   0,				  /* tp_methods */
246   0,				  /* tp_members */
247   0,				  /* tp_getset */
248   0,				  /* tp_base */
249   0,				  /* tp_dict */
250   0,				  /* tp_descr_get */
251   0,				  /* tp_descr_set */
252   0,				  /* tp_dictoffset */
253   fnpy_init,			  /* tp_init */
254   0,				  /* tp_alloc */
255 };
256