1c50c785cSJohn Marino /* GDB parameters implemented in Python
2c50c785cSJohn Marino
3*ef5ccd6cSJohn Marino Copyright (C) 2008-2013 Free Software Foundation, Inc.
4c50c785cSJohn Marino
5c50c785cSJohn Marino This file is part of GDB.
6c50c785cSJohn Marino
7c50c785cSJohn Marino This program is free software; you can redistribute it and/or modify
8c50c785cSJohn Marino it under the terms of the GNU General Public License as published by
9c50c785cSJohn Marino the Free Software Foundation; either version 3 of the License, or
10c50c785cSJohn Marino (at your option) any later version.
11c50c785cSJohn Marino
12c50c785cSJohn Marino This program is distributed in the hope that it will be useful,
13c50c785cSJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
14c50c785cSJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15c50c785cSJohn Marino GNU General Public License for more details.
16c50c785cSJohn Marino
17c50c785cSJohn Marino You should have received a copy of the GNU General Public License
18c50c785cSJohn Marino along with this program. If not, see <http://www.gnu.org/licenses/>. */
19c50c785cSJohn Marino
20c50c785cSJohn Marino
21c50c785cSJohn Marino #include "defs.h"
22c50c785cSJohn Marino #include "value.h"
23c50c785cSJohn Marino #include "exceptions.h"
24c50c785cSJohn Marino #include "python-internal.h"
25c50c785cSJohn Marino #include "charset.h"
26c50c785cSJohn Marino #include "gdbcmd.h"
27c50c785cSJohn Marino #include "cli/cli-decode.h"
28c50c785cSJohn Marino #include "completer.h"
29c50c785cSJohn Marino #include "language.h"
30c50c785cSJohn Marino #include "arch-utils.h"
31c50c785cSJohn Marino
32c50c785cSJohn Marino /* Parameter constants and their values. */
33c50c785cSJohn Marino struct parm_constant
34c50c785cSJohn Marino {
35c50c785cSJohn Marino char *name;
36c50c785cSJohn Marino int value;
37c50c785cSJohn Marino };
38c50c785cSJohn Marino
39c50c785cSJohn Marino struct parm_constant parm_constants[] =
40c50c785cSJohn Marino {
41c50c785cSJohn Marino { "PARAM_BOOLEAN", var_boolean }, /* ARI: var_boolean */
42c50c785cSJohn Marino { "PARAM_AUTO_BOOLEAN", var_auto_boolean },
43c50c785cSJohn Marino { "PARAM_UINTEGER", var_uinteger },
44c50c785cSJohn Marino { "PARAM_INTEGER", var_integer },
45c50c785cSJohn Marino { "PARAM_STRING", var_string },
46c50c785cSJohn Marino { "PARAM_STRING_NOESCAPE", var_string_noescape },
47c50c785cSJohn Marino { "PARAM_OPTIONAL_FILENAME", var_optional_filename },
48c50c785cSJohn Marino { "PARAM_FILENAME", var_filename },
49c50c785cSJohn Marino { "PARAM_ZINTEGER", var_zinteger },
50c50c785cSJohn Marino { "PARAM_ENUM", var_enum },
51c50c785cSJohn Marino { NULL, 0 }
52c50c785cSJohn Marino };
53c50c785cSJohn Marino
54c50c785cSJohn Marino /* A union that can hold anything described by enum var_types. */
55c50c785cSJohn Marino union parmpy_variable
56c50c785cSJohn Marino {
57c50c785cSJohn Marino /* Hold an integer value, for boolean and integer types. */
58c50c785cSJohn Marino int intval;
59c50c785cSJohn Marino
60c50c785cSJohn Marino /* Hold an auto_boolean. */
61c50c785cSJohn Marino enum auto_boolean autoboolval;
62c50c785cSJohn Marino
63c50c785cSJohn Marino /* Hold an unsigned integer value, for uinteger. */
64c50c785cSJohn Marino unsigned int uintval;
65c50c785cSJohn Marino
66c50c785cSJohn Marino /* Hold a string, for the various string types. */
67c50c785cSJohn Marino char *stringval;
68c50c785cSJohn Marino
69c50c785cSJohn Marino /* Hold a string, for enums. */
70c50c785cSJohn Marino const char *cstringval;
71c50c785cSJohn Marino };
72c50c785cSJohn Marino
73c50c785cSJohn Marino /* A GDB parameter. */
74c50c785cSJohn Marino struct parmpy_object
75c50c785cSJohn Marino {
76c50c785cSJohn Marino PyObject_HEAD
77c50c785cSJohn Marino
78c50c785cSJohn Marino /* The type of the parameter. */
79c50c785cSJohn Marino enum var_types type;
80c50c785cSJohn Marino
81c50c785cSJohn Marino /* The value of the parameter. */
82c50c785cSJohn Marino union parmpy_variable value;
83c50c785cSJohn Marino
84c50c785cSJohn Marino /* For an enum command, the possible values. The vector is
85c50c785cSJohn Marino allocated with xmalloc, as is each element. It is
86c50c785cSJohn Marino NULL-terminated. */
87c50c785cSJohn Marino const char **enumeration;
88c50c785cSJohn Marino };
89c50c785cSJohn Marino
90c50c785cSJohn Marino typedef struct parmpy_object parmpy_object;
91c50c785cSJohn Marino
92c50c785cSJohn Marino static PyTypeObject parmpy_object_type;
93c50c785cSJohn Marino
94c50c785cSJohn Marino /* Some handy string constants. */
95c50c785cSJohn Marino static PyObject *set_doc_cst;
96c50c785cSJohn Marino static PyObject *show_doc_cst;
97c50c785cSJohn Marino
98c50c785cSJohn Marino
99c50c785cSJohn Marino
100c50c785cSJohn Marino /* Get an attribute. */
101c50c785cSJohn Marino static PyObject *
get_attr(PyObject * obj,PyObject * attr_name)102c50c785cSJohn Marino get_attr (PyObject *obj, PyObject *attr_name)
103c50c785cSJohn Marino {
104c50c785cSJohn Marino if (PyString_Check (attr_name)
105*ef5ccd6cSJohn Marino #ifdef IS_PY3K
106*ef5ccd6cSJohn Marino && ! PyUnicode_CompareWithASCIIString (attr_name, "value"))
107*ef5ccd6cSJohn Marino #else
108c50c785cSJohn Marino && ! strcmp (PyString_AsString (attr_name), "value"))
109*ef5ccd6cSJohn Marino #endif
110c50c785cSJohn Marino {
111c50c785cSJohn Marino parmpy_object *self = (parmpy_object *) obj;
112c50c785cSJohn Marino
113c50c785cSJohn Marino return gdbpy_parameter_value (self->type, &self->value);
114c50c785cSJohn Marino }
115c50c785cSJohn Marino
116c50c785cSJohn Marino return PyObject_GenericGetAttr (obj, attr_name);
117c50c785cSJohn Marino }
118c50c785cSJohn Marino
119c50c785cSJohn Marino /* Set a parameter value from a Python value. Return 0 on success. Returns
120c50c785cSJohn Marino -1 on error, with a python exception set. */
121c50c785cSJohn Marino static int
set_parameter_value(parmpy_object * self,PyObject * value)122c50c785cSJohn Marino set_parameter_value (parmpy_object *self, PyObject *value)
123c50c785cSJohn Marino {
124c50c785cSJohn Marino int cmp;
125c50c785cSJohn Marino
126c50c785cSJohn Marino switch (self->type)
127c50c785cSJohn Marino {
128c50c785cSJohn Marino case var_string:
129c50c785cSJohn Marino case var_string_noescape:
130c50c785cSJohn Marino case var_optional_filename:
131c50c785cSJohn Marino case var_filename:
132c50c785cSJohn Marino if (! gdbpy_is_string (value)
133c50c785cSJohn Marino && (self->type == var_filename
134c50c785cSJohn Marino || value != Py_None))
135c50c785cSJohn Marino {
136c50c785cSJohn Marino PyErr_SetString (PyExc_RuntimeError,
137c50c785cSJohn Marino _("String required for filename."));
138c50c785cSJohn Marino
139c50c785cSJohn Marino return -1;
140c50c785cSJohn Marino }
141c50c785cSJohn Marino if (value == Py_None)
142c50c785cSJohn Marino {
143c50c785cSJohn Marino xfree (self->value.stringval);
144c50c785cSJohn Marino if (self->type == var_optional_filename)
145c50c785cSJohn Marino self->value.stringval = xstrdup ("");
146c50c785cSJohn Marino else
147c50c785cSJohn Marino self->value.stringval = NULL;
148c50c785cSJohn Marino }
149c50c785cSJohn Marino else
150c50c785cSJohn Marino {
151c50c785cSJohn Marino char *string;
152c50c785cSJohn Marino
153c50c785cSJohn Marino string = python_string_to_host_string (value);
154c50c785cSJohn Marino if (string == NULL)
155c50c785cSJohn Marino return -1;
156c50c785cSJohn Marino
157c50c785cSJohn Marino xfree (self->value.stringval);
158c50c785cSJohn Marino self->value.stringval = string;
159c50c785cSJohn Marino }
160c50c785cSJohn Marino break;
161c50c785cSJohn Marino
162c50c785cSJohn Marino case var_enum:
163c50c785cSJohn Marino {
164c50c785cSJohn Marino int i;
165c50c785cSJohn Marino char *str;
166c50c785cSJohn Marino
167c50c785cSJohn Marino if (! gdbpy_is_string (value))
168c50c785cSJohn Marino {
169c50c785cSJohn Marino PyErr_SetString (PyExc_RuntimeError,
170c50c785cSJohn Marino _("ENUM arguments must be a string."));
171c50c785cSJohn Marino return -1;
172c50c785cSJohn Marino }
173c50c785cSJohn Marino
174c50c785cSJohn Marino str = python_string_to_host_string (value);
175c50c785cSJohn Marino if (str == NULL)
176c50c785cSJohn Marino return -1;
177c50c785cSJohn Marino for (i = 0; self->enumeration[i]; ++i)
178c50c785cSJohn Marino if (! strcmp (self->enumeration[i], str))
179c50c785cSJohn Marino break;
180c50c785cSJohn Marino xfree (str);
181c50c785cSJohn Marino if (! self->enumeration[i])
182c50c785cSJohn Marino {
183c50c785cSJohn Marino PyErr_SetString (PyExc_RuntimeError,
184c50c785cSJohn Marino _("The value must be member of an enumeration."));
185c50c785cSJohn Marino return -1;
186c50c785cSJohn Marino }
187c50c785cSJohn Marino self->value.cstringval = self->enumeration[i];
188c50c785cSJohn Marino break;
189c50c785cSJohn Marino }
190c50c785cSJohn Marino
191c50c785cSJohn Marino case var_boolean:
192c50c785cSJohn Marino if (! PyBool_Check (value))
193c50c785cSJohn Marino {
194c50c785cSJohn Marino PyErr_SetString (PyExc_RuntimeError,
195c50c785cSJohn Marino _("A boolean argument is required."));
196c50c785cSJohn Marino return -1;
197c50c785cSJohn Marino }
198c50c785cSJohn Marino cmp = PyObject_IsTrue (value);
199c50c785cSJohn Marino if (cmp < 0)
200c50c785cSJohn Marino return -1;
201c50c785cSJohn Marino self->value.intval = cmp;
202c50c785cSJohn Marino break;
203c50c785cSJohn Marino
204c50c785cSJohn Marino case var_auto_boolean:
205c50c785cSJohn Marino if (! PyBool_Check (value) && value != Py_None)
206c50c785cSJohn Marino {
207c50c785cSJohn Marino PyErr_SetString (PyExc_RuntimeError,
208c50c785cSJohn Marino _("A boolean or None is required"));
209c50c785cSJohn Marino return -1;
210c50c785cSJohn Marino }
211c50c785cSJohn Marino
212c50c785cSJohn Marino if (value == Py_None)
213c50c785cSJohn Marino self->value.autoboolval = AUTO_BOOLEAN_AUTO;
214c50c785cSJohn Marino else
215c50c785cSJohn Marino {
216c50c785cSJohn Marino cmp = PyObject_IsTrue (value);
217c50c785cSJohn Marino if (cmp < 0 )
218c50c785cSJohn Marino return -1;
219c50c785cSJohn Marino if (cmp == 1)
220c50c785cSJohn Marino self->value.autoboolval = AUTO_BOOLEAN_TRUE;
221c50c785cSJohn Marino else
222c50c785cSJohn Marino self->value.autoboolval = AUTO_BOOLEAN_FALSE;
223c50c785cSJohn Marino }
224c50c785cSJohn Marino break;
225c50c785cSJohn Marino
226c50c785cSJohn Marino case var_integer:
227c50c785cSJohn Marino case var_zinteger:
228c50c785cSJohn Marino case var_uinteger:
229c50c785cSJohn Marino {
230c50c785cSJohn Marino long l;
231c50c785cSJohn Marino int ok;
232c50c785cSJohn Marino
233c50c785cSJohn Marino if (! PyInt_Check (value))
234c50c785cSJohn Marino {
235c50c785cSJohn Marino PyErr_SetString (PyExc_RuntimeError,
236c50c785cSJohn Marino _("The value must be integer."));
237c50c785cSJohn Marino return -1;
238c50c785cSJohn Marino }
239c50c785cSJohn Marino
240c50c785cSJohn Marino if (! gdb_py_int_as_long (value, &l))
241c50c785cSJohn Marino return -1;
242c50c785cSJohn Marino
243c50c785cSJohn Marino if (self->type == var_uinteger)
244c50c785cSJohn Marino {
245c50c785cSJohn Marino ok = (l >= 0 && l <= UINT_MAX);
246c50c785cSJohn Marino if (l == 0)
247c50c785cSJohn Marino l = UINT_MAX;
248c50c785cSJohn Marino }
249c50c785cSJohn Marino else if (self->type == var_integer)
250c50c785cSJohn Marino {
251c50c785cSJohn Marino ok = (l >= INT_MIN && l <= INT_MAX);
252c50c785cSJohn Marino if (l == 0)
253c50c785cSJohn Marino l = INT_MAX;
254c50c785cSJohn Marino }
255c50c785cSJohn Marino else
256c50c785cSJohn Marino ok = (l >= INT_MIN && l <= INT_MAX);
257c50c785cSJohn Marino
258c50c785cSJohn Marino if (! ok)
259c50c785cSJohn Marino {
260c50c785cSJohn Marino PyErr_SetString (PyExc_RuntimeError,
261c50c785cSJohn Marino _("Range exceeded."));
262c50c785cSJohn Marino return -1;
263c50c785cSJohn Marino }
264c50c785cSJohn Marino
265c50c785cSJohn Marino self->value.intval = (int) l;
266c50c785cSJohn Marino break;
267c50c785cSJohn Marino }
268c50c785cSJohn Marino
269c50c785cSJohn Marino default:
270c50c785cSJohn Marino PyErr_SetString (PyExc_RuntimeError,
271c50c785cSJohn Marino _("Unhandled type in parameter value."));
272c50c785cSJohn Marino return -1;
273c50c785cSJohn Marino }
274c50c785cSJohn Marino
275c50c785cSJohn Marino return 0;
276c50c785cSJohn Marino }
277c50c785cSJohn Marino
278c50c785cSJohn Marino /* Set an attribute. Returns -1 on error, with a python exception set. */
279c50c785cSJohn Marino static int
set_attr(PyObject * obj,PyObject * attr_name,PyObject * val)280c50c785cSJohn Marino set_attr (PyObject *obj, PyObject *attr_name, PyObject *val)
281c50c785cSJohn Marino {
282c50c785cSJohn Marino if (PyString_Check (attr_name)
283*ef5ccd6cSJohn Marino #ifdef IS_PY3K
284*ef5ccd6cSJohn Marino && ! PyUnicode_CompareWithASCIIString (attr_name, "value"))
285*ef5ccd6cSJohn Marino #else
286c50c785cSJohn Marino && ! strcmp (PyString_AsString (attr_name), "value"))
287*ef5ccd6cSJohn Marino #endif
288c50c785cSJohn Marino {
289c50c785cSJohn Marino if (!val)
290c50c785cSJohn Marino {
291c50c785cSJohn Marino PyErr_SetString (PyExc_RuntimeError,
292c50c785cSJohn Marino _("Cannot delete a parameter's value."));
293c50c785cSJohn Marino return -1;
294c50c785cSJohn Marino }
295c50c785cSJohn Marino return set_parameter_value ((parmpy_object *) obj, val);
296c50c785cSJohn Marino }
297c50c785cSJohn Marino
298c50c785cSJohn Marino return PyObject_GenericSetAttr (obj, attr_name, val);
299c50c785cSJohn Marino }
300c50c785cSJohn Marino
301c50c785cSJohn Marino /* A helper function which returns a documentation string for an
302c50c785cSJohn Marino object. */
303c50c785cSJohn Marino
304c50c785cSJohn Marino static char *
get_doc_string(PyObject * object,PyObject * attr)305c50c785cSJohn Marino get_doc_string (PyObject *object, PyObject *attr)
306c50c785cSJohn Marino {
307c50c785cSJohn Marino char *result = NULL;
308c50c785cSJohn Marino
309c50c785cSJohn Marino if (PyObject_HasAttr (object, attr))
310c50c785cSJohn Marino {
311c50c785cSJohn Marino PyObject *ds_obj = PyObject_GetAttr (object, attr);
312c50c785cSJohn Marino
313c50c785cSJohn Marino if (ds_obj && gdbpy_is_string (ds_obj))
314c50c785cSJohn Marino {
315c50c785cSJohn Marino result = python_string_to_host_string (ds_obj);
316c50c785cSJohn Marino if (result == NULL)
317c50c785cSJohn Marino gdbpy_print_stack ();
318c50c785cSJohn Marino }
319c50c785cSJohn Marino Py_XDECREF (ds_obj);
320c50c785cSJohn Marino }
321c50c785cSJohn Marino if (! result)
322c50c785cSJohn Marino result = xstrdup (_("This command is not documented."));
323c50c785cSJohn Marino return result;
324c50c785cSJohn Marino }
325c50c785cSJohn Marino
326c50c785cSJohn Marino /* Helper function which will execute a METHOD in OBJ passing the
327c50c785cSJohn Marino argument ARG. ARG can be NULL. METHOD should return a Python
328c50c785cSJohn Marino string. If this function returns NULL, there has been an error and
329c50c785cSJohn Marino the appropriate exception set. */
330c50c785cSJohn Marino static char *
call_doc_function(PyObject * obj,PyObject * method,PyObject * arg)331c50c785cSJohn Marino call_doc_function (PyObject *obj, PyObject *method, PyObject *arg)
332c50c785cSJohn Marino {
333c50c785cSJohn Marino char *data = NULL;
334c50c785cSJohn Marino PyObject *result = PyObject_CallMethodObjArgs (obj, method, arg, NULL);
335c50c785cSJohn Marino
336c50c785cSJohn Marino if (! result)
337c50c785cSJohn Marino return NULL;
338c50c785cSJohn Marino
339c50c785cSJohn Marino if (gdbpy_is_string (result))
340c50c785cSJohn Marino {
341c50c785cSJohn Marino data = python_string_to_host_string (result);
342a45ae5f8SJohn Marino Py_DECREF (result);
343c50c785cSJohn Marino if (! data)
344c50c785cSJohn Marino return NULL;
345c50c785cSJohn Marino }
346c50c785cSJohn Marino else
347c50c785cSJohn Marino {
348c50c785cSJohn Marino PyErr_SetString (PyExc_RuntimeError,
349c50c785cSJohn Marino _("Parameter must return a string value."));
350a45ae5f8SJohn Marino Py_DECREF (result);
351c50c785cSJohn Marino return NULL;
352c50c785cSJohn Marino }
353c50c785cSJohn Marino
354c50c785cSJohn Marino return data;
355c50c785cSJohn Marino }
356c50c785cSJohn Marino
357c50c785cSJohn Marino /* A callback function that is registered against the respective
358c50c785cSJohn Marino add_setshow_* set_doc prototype. This function will either call
359c50c785cSJohn Marino the Python function "get_set_string" or extract the Python
360c50c785cSJohn Marino attribute "set_doc" and return the contents as a string. If
361c50c785cSJohn Marino neither exist, insert a string indicating the Parameter is not
362c50c785cSJohn Marino documented. */
363c50c785cSJohn Marino static void
get_set_value(char * args,int from_tty,struct cmd_list_element * c)364c50c785cSJohn Marino get_set_value (char *args, int from_tty,
365c50c785cSJohn Marino struct cmd_list_element *c)
366c50c785cSJohn Marino {
367c50c785cSJohn Marino PyObject *obj = (PyObject *) get_cmd_context (c);
368c50c785cSJohn Marino char *set_doc_string;
369c50c785cSJohn Marino struct cleanup *cleanup = ensure_python_env (get_current_arch (),
370c50c785cSJohn Marino current_language);
371c50c785cSJohn Marino PyObject *set_doc_func = PyString_FromString ("get_set_string");
372c50c785cSJohn Marino
373c50c785cSJohn Marino if (! set_doc_func)
374c50c785cSJohn Marino goto error;
375c50c785cSJohn Marino
376c50c785cSJohn Marino make_cleanup_py_decref (set_doc_func);
377c50c785cSJohn Marino
378c50c785cSJohn Marino if (PyObject_HasAttr (obj, set_doc_func))
379c50c785cSJohn Marino {
380c50c785cSJohn Marino set_doc_string = call_doc_function (obj, set_doc_func, NULL);
381c50c785cSJohn Marino if (! set_doc_string)
382c50c785cSJohn Marino goto error;
383c50c785cSJohn Marino }
384c50c785cSJohn Marino else
385c50c785cSJohn Marino {
386c50c785cSJohn Marino /* We have to preserve the existing < GDB 7.3 API. If a
387c50c785cSJohn Marino callback function does not exist, then attempt to read the
388c50c785cSJohn Marino set_doc attribute. */
389c50c785cSJohn Marino set_doc_string = get_doc_string (obj, set_doc_cst);
390c50c785cSJohn Marino }
391c50c785cSJohn Marino
392c50c785cSJohn Marino make_cleanup (xfree, set_doc_string);
393c50c785cSJohn Marino fprintf_filtered (gdb_stdout, "%s\n", set_doc_string);
394c50c785cSJohn Marino
395c50c785cSJohn Marino do_cleanups (cleanup);
396c50c785cSJohn Marino return;
397c50c785cSJohn Marino
398c50c785cSJohn Marino error:
399c50c785cSJohn Marino gdbpy_print_stack ();
400c50c785cSJohn Marino do_cleanups (cleanup);
401c50c785cSJohn Marino return;
402c50c785cSJohn Marino }
403c50c785cSJohn Marino
404c50c785cSJohn Marino /* A callback function that is registered against the respective
405c50c785cSJohn Marino add_setshow_* show_doc prototype. This function will either call
406c50c785cSJohn Marino the Python function "get_show_string" or extract the Python
407c50c785cSJohn Marino attribute "show_doc" and return the contents as a string. If
408c50c785cSJohn Marino neither exist, insert a string indicating the Parameter is not
409c50c785cSJohn Marino documented. */
410c50c785cSJohn Marino static void
get_show_value(struct ui_file * file,int from_tty,struct cmd_list_element * c,const char * value)411c50c785cSJohn Marino get_show_value (struct ui_file *file, int from_tty,
412c50c785cSJohn Marino struct cmd_list_element *c,
413c50c785cSJohn Marino const char *value)
414c50c785cSJohn Marino {
415c50c785cSJohn Marino PyObject *obj = (PyObject *) get_cmd_context (c);
416c50c785cSJohn Marino char *show_doc_string = NULL;
417c50c785cSJohn Marino struct cleanup *cleanup = ensure_python_env (get_current_arch (),
418c50c785cSJohn Marino current_language);
419c50c785cSJohn Marino PyObject *show_doc_func = PyString_FromString ("get_show_string");
420c50c785cSJohn Marino
421c50c785cSJohn Marino if (! show_doc_func)
422c50c785cSJohn Marino goto error;
423c50c785cSJohn Marino
424c50c785cSJohn Marino make_cleanup_py_decref (show_doc_func);
425c50c785cSJohn Marino
426c50c785cSJohn Marino if (PyObject_HasAttr (obj, show_doc_func))
427c50c785cSJohn Marino {
428c50c785cSJohn Marino PyObject *val_obj = PyString_FromString (value);
429c50c785cSJohn Marino
430c50c785cSJohn Marino if (! val_obj)
431c50c785cSJohn Marino goto error;
432c50c785cSJohn Marino
433c50c785cSJohn Marino make_cleanup_py_decref (val_obj);
434c50c785cSJohn Marino
435c50c785cSJohn Marino show_doc_string = call_doc_function (obj, show_doc_func, val_obj);
436c50c785cSJohn Marino if (! show_doc_string)
437c50c785cSJohn Marino goto error;
438c50c785cSJohn Marino
439c50c785cSJohn Marino make_cleanup (xfree, show_doc_string);
440c50c785cSJohn Marino
441c50c785cSJohn Marino fprintf_filtered (file, "%s\n", show_doc_string);
442c50c785cSJohn Marino }
443c50c785cSJohn Marino else
444c50c785cSJohn Marino {
445c50c785cSJohn Marino /* We have to preserve the existing < GDB 7.3 API. If a
446c50c785cSJohn Marino callback function does not exist, then attempt to read the
447c50c785cSJohn Marino show_doc attribute. */
448c50c785cSJohn Marino show_doc_string = get_doc_string (obj, show_doc_cst);
449c50c785cSJohn Marino make_cleanup (xfree, show_doc_string);
450c50c785cSJohn Marino fprintf_filtered (file, "%s %s\n", show_doc_string, value);
451c50c785cSJohn Marino }
452c50c785cSJohn Marino
453c50c785cSJohn Marino do_cleanups (cleanup);
454c50c785cSJohn Marino return;
455c50c785cSJohn Marino
456c50c785cSJohn Marino error:
457c50c785cSJohn Marino gdbpy_print_stack ();
458c50c785cSJohn Marino do_cleanups (cleanup);
459c50c785cSJohn Marino return;
460c50c785cSJohn Marino }
461c50c785cSJohn Marino
462c50c785cSJohn Marino
463c50c785cSJohn Marino /* A helper function that dispatches to the appropriate add_setshow
464c50c785cSJohn Marino function. */
465c50c785cSJohn Marino static void
add_setshow_generic(int parmclass,enum command_class cmdclass,char * cmd_name,parmpy_object * self,char * set_doc,char * show_doc,char * help_doc,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)466c50c785cSJohn Marino add_setshow_generic (int parmclass, enum command_class cmdclass,
467c50c785cSJohn Marino char *cmd_name, parmpy_object *self,
468c50c785cSJohn Marino char *set_doc, char *show_doc, char *help_doc,
469c50c785cSJohn Marino struct cmd_list_element **set_list,
470c50c785cSJohn Marino struct cmd_list_element **show_list)
471c50c785cSJohn Marino {
472c50c785cSJohn Marino struct cmd_list_element *param = NULL;
473c50c785cSJohn Marino char *tmp_name = NULL;
474c50c785cSJohn Marino
475c50c785cSJohn Marino switch (parmclass)
476c50c785cSJohn Marino {
477c50c785cSJohn Marino case var_boolean:
478c50c785cSJohn Marino
479c50c785cSJohn Marino add_setshow_boolean_cmd (cmd_name, cmdclass,
480c50c785cSJohn Marino &self->value.intval, set_doc, show_doc,
481c50c785cSJohn Marino help_doc, get_set_value, get_show_value,
482c50c785cSJohn Marino set_list, show_list);
483c50c785cSJohn Marino
484c50c785cSJohn Marino break;
485c50c785cSJohn Marino
486c50c785cSJohn Marino case var_auto_boolean:
487c50c785cSJohn Marino add_setshow_auto_boolean_cmd (cmd_name, cmdclass,
488c50c785cSJohn Marino &self->value.autoboolval,
489c50c785cSJohn Marino set_doc, show_doc, help_doc,
490c50c785cSJohn Marino get_set_value, get_show_value,
491c50c785cSJohn Marino set_list, show_list);
492c50c785cSJohn Marino break;
493c50c785cSJohn Marino
494c50c785cSJohn Marino case var_uinteger:
495c50c785cSJohn Marino add_setshow_uinteger_cmd (cmd_name, cmdclass,
496c50c785cSJohn Marino &self->value.uintval, set_doc, show_doc,
497c50c785cSJohn Marino help_doc, get_set_value, get_show_value,
498c50c785cSJohn Marino set_list, show_list);
499c50c785cSJohn Marino break;
500c50c785cSJohn Marino
501c50c785cSJohn Marino case var_integer:
502c50c785cSJohn Marino add_setshow_integer_cmd (cmd_name, cmdclass,
503c50c785cSJohn Marino &self->value.intval, set_doc, show_doc,
504c50c785cSJohn Marino help_doc, get_set_value, get_show_value,
505c50c785cSJohn Marino set_list, show_list); break;
506c50c785cSJohn Marino
507c50c785cSJohn Marino case var_string:
508c50c785cSJohn Marino add_setshow_string_cmd (cmd_name, cmdclass,
509c50c785cSJohn Marino &self->value.stringval, set_doc, show_doc,
510c50c785cSJohn Marino help_doc, get_set_value, get_show_value,
511c50c785cSJohn Marino set_list, show_list); break;
512c50c785cSJohn Marino
513c50c785cSJohn Marino case var_string_noescape:
514c50c785cSJohn Marino add_setshow_string_noescape_cmd (cmd_name, cmdclass,
515c50c785cSJohn Marino &self->value.stringval,
516c50c785cSJohn Marino set_doc, show_doc, help_doc,
517c50c785cSJohn Marino get_set_value, get_show_value,
518c50c785cSJohn Marino set_list, show_list);
519c50c785cSJohn Marino
520c50c785cSJohn Marino break;
521c50c785cSJohn Marino
522c50c785cSJohn Marino case var_optional_filename:
523c50c785cSJohn Marino add_setshow_optional_filename_cmd (cmd_name, cmdclass,
524c50c785cSJohn Marino &self->value.stringval, set_doc,
525c50c785cSJohn Marino show_doc, help_doc, get_set_value,
526c50c785cSJohn Marino get_show_value, set_list,
527c50c785cSJohn Marino show_list);
528c50c785cSJohn Marino break;
529c50c785cSJohn Marino
530c50c785cSJohn Marino case var_filename:
531c50c785cSJohn Marino add_setshow_filename_cmd (cmd_name, cmdclass,
532c50c785cSJohn Marino &self->value.stringval, set_doc, show_doc,
533c50c785cSJohn Marino help_doc, get_set_value, get_show_value,
534c50c785cSJohn Marino set_list, show_list); break;
535c50c785cSJohn Marino
536c50c785cSJohn Marino case var_zinteger:
537c50c785cSJohn Marino add_setshow_zinteger_cmd (cmd_name, cmdclass,
538c50c785cSJohn Marino &self->value.intval, set_doc, show_doc,
539c50c785cSJohn Marino help_doc, get_set_value, get_show_value,
540c50c785cSJohn Marino set_list, show_list);
541c50c785cSJohn Marino break;
542c50c785cSJohn Marino
543c50c785cSJohn Marino case var_enum:
544c50c785cSJohn Marino add_setshow_enum_cmd (cmd_name, cmdclass, self->enumeration,
545c50c785cSJohn Marino &self->value.cstringval, set_doc, show_doc,
546c50c785cSJohn Marino help_doc, get_set_value, get_show_value,
547c50c785cSJohn Marino set_list, show_list);
548c50c785cSJohn Marino /* Initialize the value, just in case. */
549c50c785cSJohn Marino self->value.cstringval = self->enumeration[0];
550c50c785cSJohn Marino break;
551c50c785cSJohn Marino }
552c50c785cSJohn Marino
553c50c785cSJohn Marino /* Lookup created parameter, and register Python object against the
554c50c785cSJohn Marino parameter context. Perform this task against both lists. */
555c50c785cSJohn Marino tmp_name = cmd_name;
556c50c785cSJohn Marino param = lookup_cmd (&tmp_name, *show_list, "", 0, 1);
557c50c785cSJohn Marino if (param)
558c50c785cSJohn Marino set_cmd_context (param, self);
559c50c785cSJohn Marino
560c50c785cSJohn Marino tmp_name = cmd_name;
561c50c785cSJohn Marino param = lookup_cmd (&tmp_name, *set_list, "", 0, 1);
562c50c785cSJohn Marino if (param)
563c50c785cSJohn Marino set_cmd_context (param, self);
564c50c785cSJohn Marino }
565c50c785cSJohn Marino
566c50c785cSJohn Marino /* A helper which computes enum values. Returns 1 on success. Returns 0 on
567c50c785cSJohn Marino error, with a python exception set. */
568c50c785cSJohn Marino static int
compute_enum_values(parmpy_object * self,PyObject * enum_values)569c50c785cSJohn Marino compute_enum_values (parmpy_object *self, PyObject *enum_values)
570c50c785cSJohn Marino {
571c50c785cSJohn Marino Py_ssize_t size, i;
572c50c785cSJohn Marino struct cleanup *back_to;
573c50c785cSJohn Marino
574c50c785cSJohn Marino if (! enum_values)
575c50c785cSJohn Marino {
576c50c785cSJohn Marino PyErr_SetString (PyExc_RuntimeError,
577c50c785cSJohn Marino _("An enumeration is required for PARAM_ENUM."));
578c50c785cSJohn Marino return 0;
579c50c785cSJohn Marino }
580c50c785cSJohn Marino
581c50c785cSJohn Marino if (! PySequence_Check (enum_values))
582c50c785cSJohn Marino {
583c50c785cSJohn Marino PyErr_SetString (PyExc_RuntimeError,
584c50c785cSJohn Marino _("The enumeration is not a sequence."));
585c50c785cSJohn Marino return 0;
586c50c785cSJohn Marino }
587c50c785cSJohn Marino
588c50c785cSJohn Marino size = PySequence_Size (enum_values);
589c50c785cSJohn Marino if (size < 0)
590c50c785cSJohn Marino return 0;
591c50c785cSJohn Marino if (size == 0)
592c50c785cSJohn Marino {
593c50c785cSJohn Marino PyErr_SetString (PyExc_RuntimeError,
594c50c785cSJohn Marino _("The enumeration is empty."));
595c50c785cSJohn Marino return 0;
596c50c785cSJohn Marino }
597c50c785cSJohn Marino
598c50c785cSJohn Marino self->enumeration = xmalloc ((size + 1) * sizeof (char *));
599c50c785cSJohn Marino back_to = make_cleanup (free_current_contents, &self->enumeration);
600c50c785cSJohn Marino memset (self->enumeration, 0, (size + 1) * sizeof (char *));
601c50c785cSJohn Marino
602c50c785cSJohn Marino for (i = 0; i < size; ++i)
603c50c785cSJohn Marino {
604c50c785cSJohn Marino PyObject *item = PySequence_GetItem (enum_values, i);
605c50c785cSJohn Marino
606c50c785cSJohn Marino if (! item)
607c50c785cSJohn Marino {
608c50c785cSJohn Marino do_cleanups (back_to);
609c50c785cSJohn Marino return 0;
610c50c785cSJohn Marino }
611c50c785cSJohn Marino if (! gdbpy_is_string (item))
612c50c785cSJohn Marino {
613c50c785cSJohn Marino do_cleanups (back_to);
614c50c785cSJohn Marino PyErr_SetString (PyExc_RuntimeError,
615c50c785cSJohn Marino _("The enumeration item not a string."));
616c50c785cSJohn Marino return 0;
617c50c785cSJohn Marino }
618c50c785cSJohn Marino self->enumeration[i] = python_string_to_host_string (item);
619c50c785cSJohn Marino if (self->enumeration[i] == NULL)
620c50c785cSJohn Marino {
621c50c785cSJohn Marino do_cleanups (back_to);
622c50c785cSJohn Marino return 0;
623c50c785cSJohn Marino }
624c50c785cSJohn Marino make_cleanup (xfree, (char *) self->enumeration[i]);
625c50c785cSJohn Marino }
626c50c785cSJohn Marino
627c50c785cSJohn Marino discard_cleanups (back_to);
628c50c785cSJohn Marino return 1;
629c50c785cSJohn Marino }
630c50c785cSJohn Marino
631c50c785cSJohn Marino /* Object initializer; sets up gdb-side structures for command.
632c50c785cSJohn Marino
633c50c785cSJohn Marino Use: __init__(NAME, CMDCLASS, PARMCLASS, [ENUM])
634c50c785cSJohn Marino
635c50c785cSJohn Marino NAME is the name of the parameter. It may consist of multiple
636c50c785cSJohn Marino words, in which case the final word is the name of the new command,
637c50c785cSJohn Marino and earlier words must be prefix commands.
638c50c785cSJohn Marino
639c50c785cSJohn Marino CMDCLASS is the kind of command. It should be one of the COMMAND_*
640c50c785cSJohn Marino constants defined in the gdb module.
641c50c785cSJohn Marino
642c50c785cSJohn Marino PARMCLASS is the type of the parameter. It should be one of the
643c50c785cSJohn Marino PARAM_* constants defined in the gdb module.
644c50c785cSJohn Marino
645c50c785cSJohn Marino If PARMCLASS is PARAM_ENUM, then the final argument should be a
646c50c785cSJohn Marino collection of strings. These strings are the valid values for this
647c50c785cSJohn Marino parameter.
648c50c785cSJohn Marino
649c50c785cSJohn Marino The documentation for the parameter is taken from the doc string
650c50c785cSJohn Marino for the python class.
651c50c785cSJohn Marino
652c50c785cSJohn Marino Returns -1 on error, with a python exception set. */
653c50c785cSJohn Marino
654c50c785cSJohn Marino static int
parmpy_init(PyObject * self,PyObject * args,PyObject * kwds)655c50c785cSJohn Marino parmpy_init (PyObject *self, PyObject *args, PyObject *kwds)
656c50c785cSJohn Marino {
657c50c785cSJohn Marino parmpy_object *obj = (parmpy_object *) self;
658a45ae5f8SJohn Marino const char *name;
659c50c785cSJohn Marino char *set_doc, *show_doc, *doc;
660c50c785cSJohn Marino char *cmd_name;
661c50c785cSJohn Marino int parmclass, cmdtype;
662c50c785cSJohn Marino PyObject *enum_values = NULL;
663c50c785cSJohn Marino struct cmd_list_element **set_list, **show_list;
664c50c785cSJohn Marino volatile struct gdb_exception except;
665c50c785cSJohn Marino
666c50c785cSJohn Marino if (! PyArg_ParseTuple (args, "sii|O", &name, &cmdtype, &parmclass,
667c50c785cSJohn Marino &enum_values))
668c50c785cSJohn Marino return -1;
669c50c785cSJohn Marino
670c50c785cSJohn Marino if (cmdtype != no_class && cmdtype != class_run
671c50c785cSJohn Marino && cmdtype != class_vars && cmdtype != class_stack
672c50c785cSJohn Marino && cmdtype != class_files && cmdtype != class_support
673c50c785cSJohn Marino && cmdtype != class_info && cmdtype != class_breakpoint
674c50c785cSJohn Marino && cmdtype != class_trace && cmdtype != class_obscure
675c50c785cSJohn Marino && cmdtype != class_maintenance)
676c50c785cSJohn Marino {
677c50c785cSJohn Marino PyErr_Format (PyExc_RuntimeError, _("Invalid command class argument."));
678c50c785cSJohn Marino return -1;
679c50c785cSJohn Marino }
680c50c785cSJohn Marino
681c50c785cSJohn Marino if (parmclass != var_boolean /* ARI: var_boolean */
682c50c785cSJohn Marino && parmclass != var_auto_boolean
683c50c785cSJohn Marino && parmclass != var_uinteger && parmclass != var_integer
684c50c785cSJohn Marino && parmclass != var_string && parmclass != var_string_noescape
685c50c785cSJohn Marino && parmclass != var_optional_filename && parmclass != var_filename
686c50c785cSJohn Marino && parmclass != var_zinteger && parmclass != var_enum)
687c50c785cSJohn Marino {
688c50c785cSJohn Marino PyErr_SetString (PyExc_RuntimeError,
689c50c785cSJohn Marino _("Invalid parameter class argument."));
690c50c785cSJohn Marino return -1;
691c50c785cSJohn Marino }
692c50c785cSJohn Marino
693c50c785cSJohn Marino if (enum_values && parmclass != var_enum)
694c50c785cSJohn Marino {
695c50c785cSJohn Marino PyErr_SetString (PyExc_RuntimeError,
696c50c785cSJohn Marino _("Only PARAM_ENUM accepts a fourth argument."));
697c50c785cSJohn Marino return -1;
698c50c785cSJohn Marino }
699c50c785cSJohn Marino if (parmclass == var_enum)
700c50c785cSJohn Marino {
701c50c785cSJohn Marino if (! compute_enum_values (obj, enum_values))
702c50c785cSJohn Marino return -1;
703c50c785cSJohn Marino }
704c50c785cSJohn Marino else
705c50c785cSJohn Marino obj->enumeration = NULL;
706c50c785cSJohn Marino obj->type = (enum var_types) parmclass;
707c50c785cSJohn Marino memset (&obj->value, 0, sizeof (obj->value));
708c50c785cSJohn Marino
709c50c785cSJohn Marino cmd_name = gdbpy_parse_command_name (name, &set_list,
710c50c785cSJohn Marino &setlist);
711c50c785cSJohn Marino
712c50c785cSJohn Marino if (! cmd_name)
713c50c785cSJohn Marino return -1;
714c50c785cSJohn Marino xfree (cmd_name);
715c50c785cSJohn Marino cmd_name = gdbpy_parse_command_name (name, &show_list,
716c50c785cSJohn Marino &showlist);
717c50c785cSJohn Marino if (! cmd_name)
718c50c785cSJohn Marino return -1;
719c50c785cSJohn Marino
720c50c785cSJohn Marino set_doc = get_doc_string (self, set_doc_cst);
721c50c785cSJohn Marino show_doc = get_doc_string (self, show_doc_cst);
722c50c785cSJohn Marino doc = get_doc_string (self, gdbpy_doc_cst);
723c50c785cSJohn Marino
724c50c785cSJohn Marino Py_INCREF (self);
725c50c785cSJohn Marino
726c50c785cSJohn Marino TRY_CATCH (except, RETURN_MASK_ALL)
727c50c785cSJohn Marino {
728c50c785cSJohn Marino add_setshow_generic (parmclass, (enum command_class) cmdtype,
729c50c785cSJohn Marino cmd_name, obj,
730c50c785cSJohn Marino set_doc, show_doc,
731c50c785cSJohn Marino doc, set_list, show_list);
732c50c785cSJohn Marino }
733c50c785cSJohn Marino if (except.reason < 0)
734c50c785cSJohn Marino {
735c50c785cSJohn Marino xfree (cmd_name);
736c50c785cSJohn Marino xfree (set_doc);
737c50c785cSJohn Marino xfree (show_doc);
738c50c785cSJohn Marino xfree (doc);
739c50c785cSJohn Marino Py_DECREF (self);
740c50c785cSJohn Marino PyErr_Format (except.reason == RETURN_QUIT
741c50c785cSJohn Marino ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
742c50c785cSJohn Marino "%s", except.message);
743c50c785cSJohn Marino return -1;
744c50c785cSJohn Marino }
745c50c785cSJohn Marino return 0;
746c50c785cSJohn Marino }
747c50c785cSJohn Marino
748c50c785cSJohn Marino
749c50c785cSJohn Marino
750c50c785cSJohn Marino /* Initialize the 'parameters' module. */
751c50c785cSJohn Marino void
gdbpy_initialize_parameters(void)752c50c785cSJohn Marino gdbpy_initialize_parameters (void)
753c50c785cSJohn Marino {
754c50c785cSJohn Marino int i;
755c50c785cSJohn Marino
756a45ae5f8SJohn Marino parmpy_object_type.tp_new = PyType_GenericNew;
757c50c785cSJohn Marino if (PyType_Ready (&parmpy_object_type) < 0)
758c50c785cSJohn Marino return;
759c50c785cSJohn Marino
760c50c785cSJohn Marino set_doc_cst = PyString_FromString ("set_doc");
761c50c785cSJohn Marino if (! set_doc_cst)
762c50c785cSJohn Marino return;
763c50c785cSJohn Marino show_doc_cst = PyString_FromString ("show_doc");
764c50c785cSJohn Marino if (! show_doc_cst)
765c50c785cSJohn Marino return;
766c50c785cSJohn Marino
767c50c785cSJohn Marino for (i = 0; parm_constants[i].name; ++i)
768c50c785cSJohn Marino {
769c50c785cSJohn Marino if (PyModule_AddIntConstant (gdb_module,
770c50c785cSJohn Marino parm_constants[i].name,
771c50c785cSJohn Marino parm_constants[i].value) < 0)
772c50c785cSJohn Marino return;
773c50c785cSJohn Marino }
774c50c785cSJohn Marino
775c50c785cSJohn Marino Py_INCREF (&parmpy_object_type);
776c50c785cSJohn Marino PyModule_AddObject (gdb_module, "Parameter",
777c50c785cSJohn Marino (PyObject *) &parmpy_object_type);
778c50c785cSJohn Marino }
779c50c785cSJohn Marino
780c50c785cSJohn Marino
781c50c785cSJohn Marino
782c50c785cSJohn Marino static PyTypeObject parmpy_object_type =
783c50c785cSJohn Marino {
784*ef5ccd6cSJohn Marino PyVarObject_HEAD_INIT (NULL, 0)
785c50c785cSJohn Marino "gdb.Parameter", /*tp_name*/
786c50c785cSJohn Marino sizeof (parmpy_object), /*tp_basicsize*/
787c50c785cSJohn Marino 0, /*tp_itemsize*/
788c50c785cSJohn Marino 0, /*tp_dealloc*/
789c50c785cSJohn Marino 0, /*tp_print*/
790c50c785cSJohn Marino 0, /*tp_getattr*/
791c50c785cSJohn Marino 0, /*tp_setattr*/
792c50c785cSJohn Marino 0, /*tp_compare*/
793c50c785cSJohn Marino 0, /*tp_repr*/
794c50c785cSJohn Marino 0, /*tp_as_number*/
795c50c785cSJohn Marino 0, /*tp_as_sequence*/
796c50c785cSJohn Marino 0, /*tp_as_mapping*/
797c50c785cSJohn Marino 0, /*tp_hash */
798c50c785cSJohn Marino 0, /*tp_call*/
799c50c785cSJohn Marino 0, /*tp_str*/
800c50c785cSJohn Marino get_attr, /*tp_getattro*/
801c50c785cSJohn Marino set_attr, /*tp_setattro*/
802c50c785cSJohn Marino 0, /*tp_as_buffer*/
803c50c785cSJohn Marino Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
804c50c785cSJohn Marino "GDB parameter object", /* tp_doc */
805c50c785cSJohn Marino 0, /* tp_traverse */
806c50c785cSJohn Marino 0, /* tp_clear */
807c50c785cSJohn Marino 0, /* tp_richcompare */
808c50c785cSJohn Marino 0, /* tp_weaklistoffset */
809c50c785cSJohn Marino 0, /* tp_iter */
810c50c785cSJohn Marino 0, /* tp_iternext */
811c50c785cSJohn Marino 0, /* tp_methods */
812c50c785cSJohn Marino 0, /* tp_members */
813c50c785cSJohn Marino 0, /* tp_getset */
814c50c785cSJohn Marino 0, /* tp_base */
815c50c785cSJohn Marino 0, /* tp_dict */
816c50c785cSJohn Marino 0, /* tp_descr_get */
817c50c785cSJohn Marino 0, /* tp_descr_set */
818c50c785cSJohn Marino 0, /* tp_dictoffset */
819c50c785cSJohn Marino parmpy_init, /* tp_init */
820c50c785cSJohn Marino 0, /* tp_alloc */
821c50c785cSJohn Marino };
822