py-function.c revision 1.1
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
32static PyTypeObject fnpy_object_type
33    CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("PyObject");
34
35
36
37static PyObject *
38convert_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
61static struct value *
62fnpy_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
165static int
166fnpy_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
203int
204gdbpy_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
216static 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