1 /* GDB parameters implemented in Python
3 Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
23 #include "exceptions.h"
24 #include "python-internal.h"
27 #include "cli/cli-decode.h"
28 #include "completer.h"
30 /* Parameter constants and their values. */
37 struct parm_constant parm_constants[] =
39 { "PARAM_BOOLEAN", var_boolean }, /* ARI: var_boolean */
40 { "PARAM_AUTO_BOOLEAN", var_auto_boolean },
41 { "PARAM_UINTEGER", var_uinteger },
42 { "PARAM_INTEGER", var_integer },
43 { "PARAM_STRING", var_string },
44 { "PARAM_STRING_NOESCAPE", var_string_noescape },
45 { "PARAM_OPTIONAL_FILENAME", var_optional_filename },
46 { "PARAM_FILENAME", var_filename },
47 { "PARAM_ZINTEGER", var_zinteger },
48 { "PARAM_ENUM", var_enum },
52 /* A union that can hold anything described by enum var_types. */
55 /* Hold an integer value, for boolean and integer types. */
58 /* Hold an auto_boolean. */
59 enum auto_boolean autoboolval;
61 /* Hold an unsigned integer value, for uinteger. */
64 /* Hold a string, for the various string types. */
67 /* Hold a string, for enums. */
68 const char *cstringval;
71 /* A GDB parameter. */
76 /* The type of the parameter. */
79 /* The value of the parameter. */
80 union parmpy_variable value;
82 /* For an enum command, the possible values. The vector is
83 allocated with xmalloc, as is each element. It is
85 const char **enumeration;
88 typedef struct parmpy_object parmpy_object;
90 static PyTypeObject parmpy_object_type;
92 /* Some handy string constants. */
93 static PyObject *set_doc_cst;
94 static PyObject *show_doc_cst;
98 /* Get an attribute. */
100 get_attr (PyObject *obj, PyObject *attr_name)
102 if (PyString_Check (attr_name)
103 && ! strcmp (PyString_AsString (attr_name), "value"))
105 parmpy_object *self = (parmpy_object *) obj;
107 return gdbpy_parameter_value (self->type, &self->value);
110 return PyObject_GenericGetAttr (obj, attr_name);
113 /* Set a parameter value from a Python value. Return 0 on success, -1
116 set_parameter_value (parmpy_object *self, PyObject *value)
123 case var_string_noescape:
124 case var_optional_filename:
126 if (! gdbpy_is_string (value)
127 && (self->type == var_filename
128 || value != Py_None))
130 PyErr_SetString (PyExc_RuntimeError,
131 _("String required for filename."));
135 if (self->value.stringval)
136 xfree (self->value.stringval);
137 if (value == Py_None)
139 if (self->type == var_optional_filename)
140 self->value.stringval = xstrdup ("");
142 self->value.stringval = NULL;
145 self->value.stringval = python_string_to_host_string (value);
153 if (! gdbpy_is_string (value))
155 PyErr_SetString (PyExc_RuntimeError,
156 _("ENUM arguments must be a string."));
160 str = python_string_to_host_string (value);
161 for (i = 0; self->enumeration[i]; ++i)
162 if (! strcmp (self->enumeration[i], str))
165 if (! self->enumeration[i])
167 PyErr_SetString (PyExc_RuntimeError,
168 _("The value must be member of an enumeration."));
171 self->value.cstringval = self->enumeration[i];
176 if (! PyBool_Check (value))
178 PyErr_SetString (PyExc_RuntimeError,
179 _("A boolean argument is required."));
182 cmp = PyObject_IsTrue (value);
185 self->value.intval = cmp;
188 case var_auto_boolean:
189 if (! PyBool_Check (value) && value != Py_None)
191 PyErr_SetString (PyExc_RuntimeError,
192 _("A boolean or None is required"));
196 if (value == Py_None)
197 self->value.autoboolval = AUTO_BOOLEAN_AUTO;
200 cmp = PyObject_IsTrue (value);
204 self->value.autoboolval = AUTO_BOOLEAN_TRUE;
206 self->value.autoboolval = AUTO_BOOLEAN_FALSE;
218 if (! PyInt_Check (value))
220 PyErr_SetString (PyExc_RuntimeError,
221 _("The value must be integer."));
225 l = PyInt_AsLong (value);
226 if (self->type == var_uinteger)
228 ok = (l >= 0 && l <= UINT_MAX);
232 else if (self->type == var_integer)
234 ok = (l >= INT_MIN && l <= INT_MAX);
239 ok = (l >= INT_MIN && l <= INT_MAX);
243 PyErr_SetString (PyExc_RuntimeError,
244 _("Range exceeded."));
248 self->value.intval = (int) l;
253 PyErr_SetString (PyExc_RuntimeError,
254 _("Unhandled type in parameter value."));
261 /* Set an attribute. */
263 set_attr (PyObject *obj, PyObject *attr_name, PyObject *val)
265 if (PyString_Check (attr_name)
266 && ! strcmp (PyString_AsString (attr_name), "value"))
270 PyErr_SetString (PyExc_RuntimeError,
271 _("Cannot delete a parameter's value."));
274 return set_parameter_value ((parmpy_object *) obj, val);
277 return PyObject_GenericSetAttr (obj, attr_name, val);
282 /* A helper function that dispatches to the appropriate add_setshow
285 add_setshow_generic (int parmclass, enum command_class cmdclass,
286 char *cmd_name, parmpy_object *self,
287 char *set_doc, char *show_doc, char *help_doc,
288 struct cmd_list_element **set_list,
289 struct cmd_list_element **show_list)
294 add_setshow_boolean_cmd (cmd_name, cmdclass, &self->value.intval,
295 set_doc, show_doc, help_doc,
296 NULL, NULL, set_list, show_list);
299 case var_auto_boolean:
300 add_setshow_auto_boolean_cmd (cmd_name, cmdclass,
301 &self->value.autoboolval,
302 set_doc, show_doc, help_doc,
303 NULL, NULL, set_list, show_list);
307 add_setshow_uinteger_cmd (cmd_name, cmdclass, &self->value.uintval,
308 set_doc, show_doc, help_doc,
309 NULL, NULL, set_list, show_list);
313 add_setshow_integer_cmd (cmd_name, cmdclass, &self->value.intval,
314 set_doc, show_doc, help_doc,
315 NULL, NULL, set_list, show_list);
319 add_setshow_string_cmd (cmd_name, cmdclass, &self->value.stringval,
320 set_doc, show_doc, help_doc,
321 NULL, NULL, set_list, show_list);
324 case var_string_noescape:
325 add_setshow_string_noescape_cmd (cmd_name, cmdclass,
326 &self->value.stringval,
327 set_doc, show_doc, help_doc,
328 NULL, NULL, set_list, show_list);
331 case var_optional_filename:
332 add_setshow_optional_filename_cmd (cmd_name, cmdclass,
333 &self->value.stringval,
334 set_doc, show_doc, help_doc,
335 NULL, NULL, set_list, show_list);
339 add_setshow_filename_cmd (cmd_name, cmdclass, &self->value.stringval,
340 set_doc, show_doc, help_doc,
341 NULL, NULL, set_list, show_list);
345 add_setshow_zinteger_cmd (cmd_name, cmdclass, &self->value.intval,
346 set_doc, show_doc, help_doc,
347 NULL, NULL, set_list, show_list);
351 add_setshow_enum_cmd (cmd_name, cmdclass, self->enumeration,
352 &self->value.cstringval,
353 set_doc, show_doc, help_doc,
354 NULL, NULL, set_list, show_list);
355 /* Initialize the value, just in case. */
356 self->value.cstringval = self->enumeration[0];
361 /* A helper which computes enum values. Returns 1 on success, 0 on
364 compute_enum_values (parmpy_object *self, PyObject *enum_values)
370 PyErr_SetString (PyExc_RuntimeError,
371 _("An enumeration is required for PARAM_ENUM."));
375 if (! PySequence_Check (enum_values))
377 PyErr_SetString (PyExc_RuntimeError,
378 _("The enumeration is not a sequence."));
382 size = PySequence_Size (enum_values);
387 PyErr_SetString (PyExc_RuntimeError,
388 _("The enumeration is empty."));
392 self->enumeration = xmalloc ((size + 1) * sizeof (char *));
393 memset (self->enumeration, 0, (size + 1) * sizeof (char *));
395 for (i = 0; i < size; ++i)
397 PyObject *item = PySequence_GetItem (enum_values, i);
401 if (! gdbpy_is_string (item))
403 PyErr_SetString (PyExc_RuntimeError,
404 _("The enumeration item not a string."));
407 self->enumeration[i] = python_string_to_host_string (item);
413 /* A helper function which returns a documentation string for an
416 get_doc_string (PyObject *object, PyObject *attr)
420 if (PyObject_HasAttr (object, attr))
422 PyObject *ds_obj = PyObject_GetAttr (object, attr);
424 if (ds_obj && gdbpy_is_string (ds_obj))
425 result = python_string_to_host_string (ds_obj);
428 result = xstrdup (_("This command is not documented."));
432 /* Object initializer; sets up gdb-side structures for command.
434 Use: __init__(NAME, CMDCLASS, PARMCLASS, [ENUM])
436 NAME is the name of the parameter. It may consist of multiple
437 words, in which case the final word is the name of the new command,
438 and earlier words must be prefix commands.
440 CMDCLASS is the kind of command. It should be one of the COMMAND_*
441 constants defined in the gdb module.
443 PARMCLASS is the type of the parameter. It should be one of the
444 PARAM_* constants defined in the gdb module.
446 If PARMCLASS is PARAM_ENUM, then the final argument should be a
447 collection of strings. These strings are the valid values for this
450 The documentation for the parameter is taken from the doc string
451 for the python class.
455 parmpy_init (PyObject *self, PyObject *args, PyObject *kwds)
457 parmpy_object *obj = (parmpy_object *) self;
459 char *set_doc, *show_doc, *doc;
461 int parmclass, cmdtype;
462 PyObject *enum_values = NULL;
463 struct cmd_list_element **set_list, **show_list;
464 volatile struct gdb_exception except;
466 if (! PyArg_ParseTuple (args, "sii|O", &name, &cmdtype, &parmclass,
470 if (cmdtype != no_class && cmdtype != class_run
471 && cmdtype != class_vars && cmdtype != class_stack
472 && cmdtype != class_files && cmdtype != class_support
473 && cmdtype != class_info && cmdtype != class_breakpoint
474 && cmdtype != class_trace && cmdtype != class_obscure
475 && cmdtype != class_maintenance)
477 PyErr_Format (PyExc_RuntimeError, _("Invalid command class argument."));
481 if (parmclass != var_boolean /* ARI: var_boolean */
482 && parmclass != var_auto_boolean
483 && parmclass != var_uinteger && parmclass != var_integer
484 && parmclass != var_string && parmclass != var_string_noescape
485 && parmclass != var_optional_filename && parmclass != var_filename
486 && parmclass != var_zinteger && parmclass != var_enum)
488 PyErr_SetString (PyExc_RuntimeError, _("Invalid parameter class argument."));
492 if (enum_values && parmclass != var_enum)
494 PyErr_SetString (PyExc_RuntimeError,
495 _("Only PARAM_ENUM accepts a fourth argument."));
498 if (parmclass == var_enum)
500 if (! compute_enum_values (obj, enum_values))
504 obj->enumeration = NULL;
505 obj->type = (enum var_types) parmclass;
506 memset (&obj->value, 0, sizeof (obj->value));
508 cmd_name = gdbpy_parse_command_name (name, &set_list,
514 cmd_name = gdbpy_parse_command_name (name, &show_list,
519 set_doc = get_doc_string (self, set_doc_cst);
520 show_doc = get_doc_string (self, show_doc_cst);
521 doc = get_doc_string (self, gdbpy_doc_cst);
525 TRY_CATCH (except, RETURN_MASK_ALL)
527 add_setshow_generic (parmclass, (enum command_class) cmdtype,
530 doc, set_list, show_list);
532 if (except.reason < 0)
539 PyErr_Format (except.reason == RETURN_QUIT
540 ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
541 "%s", except.message);
549 /* Initialize the 'parameters' module. */
551 gdbpy_initialize_parameters (void)
555 if (PyType_Ready (&parmpy_object_type) < 0)
558 set_doc_cst = PyString_FromString ("set_doc");
561 show_doc_cst = PyString_FromString ("show_doc");
565 for (i = 0; parm_constants[i].name; ++i)
567 if (PyModule_AddIntConstant (gdb_module,
568 parm_constants[i].name,
569 parm_constants[i].value) < 0)
573 Py_INCREF (&parmpy_object_type);
574 PyModule_AddObject (gdb_module, "Parameter",
575 (PyObject *) &parmpy_object_type);
580 static PyTypeObject parmpy_object_type =
582 PyObject_HEAD_INIT (NULL)
584 "gdb.Parameter", /*tp_name*/
585 sizeof (parmpy_object), /*tp_basicsize*/
594 0, /*tp_as_sequence*/
599 get_attr, /*tp_getattro*/
600 set_attr, /*tp_setattro*/
602 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
603 "GDB parameter object", /* tp_doc */
606 0, /* tp_richcompare */
607 0, /* tp_weaklistoffset */
615 0, /* tp_descr_get */
616 0, /* tp_descr_set */
617 0, /* tp_dictoffset */
618 parmpy_init, /* tp_init */
620 PyType_GenericNew /* tp_new */