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