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