xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/python/py-function.c (revision 99e23f81b2b10aef1a10b03588663e472627bb76)
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 
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 
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 };
238