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