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