Turn gdbpy_ref into a template
[deliverable/binutils-gdb.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.034021 seconds and 4 git commands to generate.