]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/python/py-param.c
990e9cbb2a3b3eda77028934f41d2711a9b9c6ad
[thirdparty/binutils-gdb.git] / gdb / python / py-param.c
1 /* GDB parameters implemented in Python
2
3 Copyright (C) 2008, 2009, 2010, 2011 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 "exceptions.h"
24 #include "python-internal.h"
25 #include "charset.h"
26 #include "gdbcmd.h"
27 #include "cli/cli-decode.h"
28 #include "completer.h"
29
30 /* Parameter constants and their values. */
31 struct parm_constant
32 {
33 char *name;
34 int value;
35 };
36
37 struct parm_constant parm_constants[] =
38 {
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 },
49 { NULL, 0 }
50 };
51
52 /* A union that can hold anything described by enum var_types. */
53 union parmpy_variable
54 {
55 /* Hold an integer value, for boolean and integer types. */
56 int intval;
57
58 /* Hold an auto_boolean. */
59 enum auto_boolean autoboolval;
60
61 /* Hold an unsigned integer value, for uinteger. */
62 unsigned int uintval;
63
64 /* Hold a string, for the various string types. */
65 char *stringval;
66
67 /* Hold a string, for enums. */
68 const char *cstringval;
69 };
70
71 /* A GDB parameter. */
72 struct parmpy_object
73 {
74 PyObject_HEAD
75
76 /* The type of the parameter. */
77 enum var_types type;
78
79 /* The value of the parameter. */
80 union parmpy_variable value;
81
82 /* For an enum command, the possible values. The vector is
83 allocated with xmalloc, as is each element. It is
84 NULL-terminated. */
85 const char **enumeration;
86 };
87
88 typedef struct parmpy_object parmpy_object;
89
90 static PyTypeObject parmpy_object_type;
91
92 /* Some handy string constants. */
93 static PyObject *set_doc_cst;
94 static PyObject *show_doc_cst;
95
96 \f
97
98 /* Get an attribute. */
99 static PyObject *
100 get_attr (PyObject *obj, PyObject *attr_name)
101 {
102 if (PyString_Check (attr_name)
103 && ! strcmp (PyString_AsString (attr_name), "value"))
104 {
105 parmpy_object *self = (parmpy_object *) obj;
106
107 return gdbpy_parameter_value (self->type, &self->value);
108 }
109
110 return PyObject_GenericGetAttr (obj, attr_name);
111 }
112
113 /* Set a parameter value from a Python value. Return 0 on success. Returns
114 -1 on error, with a python exception set. */
115 static int
116 set_parameter_value (parmpy_object *self, PyObject *value)
117 {
118 int cmp;
119
120 switch (self->type)
121 {
122 case var_string:
123 case var_string_noescape:
124 case var_optional_filename:
125 case var_filename:
126 if (! gdbpy_is_string (value)
127 && (self->type == var_filename
128 || value != Py_None))
129 {
130 PyErr_SetString (PyExc_RuntimeError,
131 _("String required for filename."));
132
133 return -1;
134 }
135 if (value == Py_None)
136 {
137 xfree (self->value.stringval);
138 if (self->type == var_optional_filename)
139 self->value.stringval = xstrdup ("");
140 else
141 self->value.stringval = NULL;
142 }
143 else
144 {
145 char *string;
146
147 string = python_string_to_host_string (value);
148 if (string == NULL)
149 return -1;
150
151 xfree (self->value.stringval);
152 self->value.stringval = string;
153 }
154 break;
155
156 case var_enum:
157 {
158 int i;
159 char *str;
160
161 if (! gdbpy_is_string (value))
162 {
163 PyErr_SetString (PyExc_RuntimeError,
164 _("ENUM arguments must be a string."));
165 return -1;
166 }
167
168 str = python_string_to_host_string (value);
169 if (str == NULL)
170 return -1;
171 for (i = 0; self->enumeration[i]; ++i)
172 if (! strcmp (self->enumeration[i], str))
173 break;
174 xfree (str);
175 if (! self->enumeration[i])
176 {
177 PyErr_SetString (PyExc_RuntimeError,
178 _("The value must be member of an enumeration."));
179 return -1;
180 }
181 self->value.cstringval = self->enumeration[i];
182 break;
183 }
184
185 case var_boolean:
186 if (! PyBool_Check (value))
187 {
188 PyErr_SetString (PyExc_RuntimeError,
189 _("A boolean argument is required."));
190 return -1;
191 }
192 cmp = PyObject_IsTrue (value);
193 if (cmp < 0)
194 return -1;
195 self->value.intval = cmp;
196 break;
197
198 case var_auto_boolean:
199 if (! PyBool_Check (value) && value != Py_None)
200 {
201 PyErr_SetString (PyExc_RuntimeError,
202 _("A boolean or None is required"));
203 return -1;
204 }
205
206 if (value == Py_None)
207 self->value.autoboolval = AUTO_BOOLEAN_AUTO;
208 else
209 {
210 cmp = PyObject_IsTrue (value);
211 if (cmp < 0 )
212 return -1;
213 if (cmp == 1)
214 self->value.autoboolval = AUTO_BOOLEAN_TRUE;
215 else
216 self->value.autoboolval = AUTO_BOOLEAN_FALSE;
217
218 break;
219 }
220
221 case var_integer:
222 case var_zinteger:
223 case var_uinteger:
224 {
225 long l;
226 int ok;
227
228 if (! PyInt_Check (value))
229 {
230 PyErr_SetString (PyExc_RuntimeError,
231 _("The value must be integer."));
232 return -1;
233 }
234
235 l = PyInt_AsLong (value);
236 if (self->type == var_uinteger)
237 {
238 ok = (l >= 0 && l <= UINT_MAX);
239 if (l == 0)
240 l = UINT_MAX;
241 }
242 else if (self->type == var_integer)
243 {
244 ok = (l >= INT_MIN && l <= INT_MAX);
245 if (l == 0)
246 l = INT_MAX;
247 }
248 else
249 ok = (l >= INT_MIN && l <= INT_MAX);
250
251 if (! ok)
252 {
253 PyErr_SetString (PyExc_RuntimeError,
254 _("Range exceeded."));
255 return -1;
256 }
257
258 self->value.intval = (int) l;
259 break;
260 }
261
262 default:
263 PyErr_SetString (PyExc_RuntimeError,
264 _("Unhandled type in parameter value."));
265 return -1;
266 }
267
268 return 0;
269 }
270
271 /* Set an attribute. Returns -1 on error, with a python exception set. */
272 static int
273 set_attr (PyObject *obj, PyObject *attr_name, PyObject *val)
274 {
275 if (PyString_Check (attr_name)
276 && ! strcmp (PyString_AsString (attr_name), "value"))
277 {
278 if (!val)
279 {
280 PyErr_SetString (PyExc_RuntimeError,
281 _("Cannot delete a parameter's value."));
282 return -1;
283 }
284 return set_parameter_value ((parmpy_object *) obj, val);
285 }
286
287 return PyObject_GenericSetAttr (obj, attr_name, val);
288 }
289
290 \f
291
292 /* A helper function that dispatches to the appropriate add_setshow
293 function. */
294 static void
295 add_setshow_generic (int parmclass, enum command_class cmdclass,
296 char *cmd_name, parmpy_object *self,
297 char *set_doc, char *show_doc, char *help_doc,
298 struct cmd_list_element **set_list,
299 struct cmd_list_element **show_list)
300 {
301 switch (parmclass)
302 {
303 case var_boolean:
304 add_setshow_boolean_cmd (cmd_name, cmdclass, &self->value.intval,
305 set_doc, show_doc, help_doc,
306 NULL, NULL, set_list, show_list);
307 break;
308
309 case var_auto_boolean:
310 add_setshow_auto_boolean_cmd (cmd_name, cmdclass,
311 &self->value.autoboolval,
312 set_doc, show_doc, help_doc,
313 NULL, NULL, set_list, show_list);
314 break;
315
316 case var_uinteger:
317 add_setshow_uinteger_cmd (cmd_name, cmdclass, &self->value.uintval,
318 set_doc, show_doc, help_doc,
319 NULL, NULL, set_list, show_list);
320 break;
321
322 case var_integer:
323 add_setshow_integer_cmd (cmd_name, cmdclass, &self->value.intval,
324 set_doc, show_doc, help_doc,
325 NULL, NULL, set_list, show_list);
326 break;
327
328 case var_string:
329 add_setshow_string_cmd (cmd_name, cmdclass, &self->value.stringval,
330 set_doc, show_doc, help_doc,
331 NULL, NULL, set_list, show_list);
332 break;
333
334 case var_string_noescape:
335 add_setshow_string_noescape_cmd (cmd_name, cmdclass,
336 &self->value.stringval,
337 set_doc, show_doc, help_doc,
338 NULL, NULL, set_list, show_list);
339 break;
340
341 case var_optional_filename:
342 add_setshow_optional_filename_cmd (cmd_name, cmdclass,
343 &self->value.stringval,
344 set_doc, show_doc, help_doc,
345 NULL, NULL, set_list, show_list);
346 break;
347
348 case var_filename:
349 add_setshow_filename_cmd (cmd_name, cmdclass, &self->value.stringval,
350 set_doc, show_doc, help_doc,
351 NULL, NULL, set_list, show_list);
352 break;
353
354 case var_zinteger:
355 add_setshow_zinteger_cmd (cmd_name, cmdclass, &self->value.intval,
356 set_doc, show_doc, help_doc,
357 NULL, NULL, set_list, show_list);
358 break;
359
360 case var_enum:
361 add_setshow_enum_cmd (cmd_name, cmdclass, self->enumeration,
362 &self->value.cstringval,
363 set_doc, show_doc, help_doc,
364 NULL, NULL, set_list, show_list);
365 /* Initialize the value, just in case. */
366 self->value.cstringval = self->enumeration[0];
367 break;
368 }
369 }
370
371 /* A helper which computes enum values. Returns 1 on success. Returns 0 on
372 error, with a python exception set. */
373 static int
374 compute_enum_values (parmpy_object *self, PyObject *enum_values)
375 {
376 Py_ssize_t size, i;
377 struct cleanup *back_to;
378
379 if (! enum_values)
380 {
381 PyErr_SetString (PyExc_RuntimeError,
382 _("An enumeration is required for PARAM_ENUM."));
383 return 0;
384 }
385
386 if (! PySequence_Check (enum_values))
387 {
388 PyErr_SetString (PyExc_RuntimeError,
389 _("The enumeration is not a sequence."));
390 return 0;
391 }
392
393 size = PySequence_Size (enum_values);
394 if (size < 0)
395 return 0;
396 if (size == 0)
397 {
398 PyErr_SetString (PyExc_RuntimeError,
399 _("The enumeration is empty."));
400 return 0;
401 }
402
403 self->enumeration = xmalloc ((size + 1) * sizeof (char *));
404 back_to = make_cleanup (free_current_contents, &self->enumeration);
405 memset (self->enumeration, 0, (size + 1) * sizeof (char *));
406
407 for (i = 0; i < size; ++i)
408 {
409 PyObject *item = PySequence_GetItem (enum_values, i);
410
411 if (! item)
412 {
413 do_cleanups (back_to);
414 return 0;
415 }
416 if (! gdbpy_is_string (item))
417 {
418 do_cleanups (back_to);
419 PyErr_SetString (PyExc_RuntimeError,
420 _("The enumeration item not a string."));
421 return 0;
422 }
423 self->enumeration[i] = python_string_to_host_string (item);
424 if (self->enumeration[i] == NULL)
425 {
426 do_cleanups (back_to);
427 return 0;
428 }
429 make_cleanup (xfree, (char *) self->enumeration[i]);
430 }
431
432 discard_cleanups (back_to);
433 return 1;
434 }
435
436 /* A helper function which returns a documentation string for an
437 object. */
438 static char *
439 get_doc_string (PyObject *object, PyObject *attr)
440 {
441 char *result = NULL;
442
443 if (PyObject_HasAttr (object, attr))
444 {
445 PyObject *ds_obj = PyObject_GetAttr (object, attr);
446
447 if (ds_obj && gdbpy_is_string (ds_obj))
448 {
449 result = python_string_to_host_string (ds_obj);
450 if (result == NULL)
451 gdbpy_print_stack ();
452 }
453 }
454 if (! result)
455 result = xstrdup (_("This command is not documented."));
456 return result;
457 }
458
459 /* Object initializer; sets up gdb-side structures for command.
460
461 Use: __init__(NAME, CMDCLASS, PARMCLASS, [ENUM])
462
463 NAME is the name of the parameter. It may consist of multiple
464 words, in which case the final word is the name of the new command,
465 and earlier words must be prefix commands.
466
467 CMDCLASS is the kind of command. It should be one of the COMMAND_*
468 constants defined in the gdb module.
469
470 PARMCLASS is the type of the parameter. It should be one of the
471 PARAM_* constants defined in the gdb module.
472
473 If PARMCLASS is PARAM_ENUM, then the final argument should be a
474 collection of strings. These strings are the valid values for this
475 parameter.
476
477 The documentation for the parameter is taken from the doc string
478 for the python class.
479
480 Returns -1 on error, with a python exception set. */
481
482 static int
483 parmpy_init (PyObject *self, PyObject *args, PyObject *kwds)
484 {
485 parmpy_object *obj = (parmpy_object *) self;
486 char *name;
487 char *set_doc, *show_doc, *doc;
488 char *cmd_name;
489 int parmclass, cmdtype;
490 PyObject *enum_values = NULL;
491 struct cmd_list_element **set_list, **show_list;
492 volatile struct gdb_exception except;
493
494 if (! PyArg_ParseTuple (args, "sii|O", &name, &cmdtype, &parmclass,
495 &enum_values))
496 return -1;
497
498 if (cmdtype != no_class && cmdtype != class_run
499 && cmdtype != class_vars && cmdtype != class_stack
500 && cmdtype != class_files && cmdtype != class_support
501 && cmdtype != class_info && cmdtype != class_breakpoint
502 && cmdtype != class_trace && cmdtype != class_obscure
503 && cmdtype != class_maintenance)
504 {
505 PyErr_Format (PyExc_RuntimeError, _("Invalid command class argument."));
506 return -1;
507 }
508
509 if (parmclass != var_boolean /* ARI: var_boolean */
510 && parmclass != var_auto_boolean
511 && parmclass != var_uinteger && parmclass != var_integer
512 && parmclass != var_string && parmclass != var_string_noescape
513 && parmclass != var_optional_filename && parmclass != var_filename
514 && parmclass != var_zinteger && parmclass != var_enum)
515 {
516 PyErr_SetString (PyExc_RuntimeError, _("Invalid parameter class argument."));
517 return -1;
518 }
519
520 if (enum_values && parmclass != var_enum)
521 {
522 PyErr_SetString (PyExc_RuntimeError,
523 _("Only PARAM_ENUM accepts a fourth argument."));
524 return -1;
525 }
526 if (parmclass == var_enum)
527 {
528 if (! compute_enum_values (obj, enum_values))
529 return -1;
530 }
531 else
532 obj->enumeration = NULL;
533 obj->type = (enum var_types) parmclass;
534 memset (&obj->value, 0, sizeof (obj->value));
535
536 cmd_name = gdbpy_parse_command_name (name, &set_list,
537 &setlist);
538
539 if (! cmd_name)
540 return -1;
541 xfree (cmd_name);
542 cmd_name = gdbpy_parse_command_name (name, &show_list,
543 &showlist);
544 if (! cmd_name)
545 return -1;
546
547 set_doc = get_doc_string (self, set_doc_cst);
548 show_doc = get_doc_string (self, show_doc_cst);
549 doc = get_doc_string (self, gdbpy_doc_cst);
550
551 Py_INCREF (self);
552
553 TRY_CATCH (except, RETURN_MASK_ALL)
554 {
555 add_setshow_generic (parmclass, (enum command_class) cmdtype,
556 cmd_name, obj,
557 set_doc, show_doc,
558 doc, set_list, show_list);
559 }
560 if (except.reason < 0)
561 {
562 xfree (cmd_name);
563 xfree (set_doc);
564 xfree (show_doc);
565 xfree (doc);
566 Py_DECREF (self);
567 PyErr_Format (except.reason == RETURN_QUIT
568 ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
569 "%s", except.message);
570 return -1;
571 }
572 return 0;
573 }
574
575 \f
576
577 /* Initialize the 'parameters' module. */
578 void
579 gdbpy_initialize_parameters (void)
580 {
581 int i;
582
583 if (PyType_Ready (&parmpy_object_type) < 0)
584 return;
585
586 set_doc_cst = PyString_FromString ("set_doc");
587 if (! set_doc_cst)
588 return;
589 show_doc_cst = PyString_FromString ("show_doc");
590 if (! show_doc_cst)
591 return;
592
593 for (i = 0; parm_constants[i].name; ++i)
594 {
595 if (PyModule_AddIntConstant (gdb_module,
596 parm_constants[i].name,
597 parm_constants[i].value) < 0)
598 return;
599 }
600
601 Py_INCREF (&parmpy_object_type);
602 PyModule_AddObject (gdb_module, "Parameter",
603 (PyObject *) &parmpy_object_type);
604 }
605
606 \f
607
608 static PyTypeObject parmpy_object_type =
609 {
610 PyObject_HEAD_INIT (NULL)
611 0, /*ob_size*/
612 "gdb.Parameter", /*tp_name*/
613 sizeof (parmpy_object), /*tp_basicsize*/
614 0, /*tp_itemsize*/
615 0, /*tp_dealloc*/
616 0, /*tp_print*/
617 0, /*tp_getattr*/
618 0, /*tp_setattr*/
619 0, /*tp_compare*/
620 0, /*tp_repr*/
621 0, /*tp_as_number*/
622 0, /*tp_as_sequence*/
623 0, /*tp_as_mapping*/
624 0, /*tp_hash */
625 0, /*tp_call*/
626 0, /*tp_str*/
627 get_attr, /*tp_getattro*/
628 set_attr, /*tp_setattro*/
629 0, /*tp_as_buffer*/
630 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
631 "GDB parameter object", /* tp_doc */
632 0, /* tp_traverse */
633 0, /* tp_clear */
634 0, /* tp_richcompare */
635 0, /* tp_weaklistoffset */
636 0, /* tp_iter */
637 0, /* tp_iternext */
638 0, /* tp_methods */
639 0, /* tp_members */
640 0, /* tp_getset */
641 0, /* tp_base */
642 0, /* tp_dict */
643 0, /* tp_descr_get */
644 0, /* tp_descr_set */
645 0, /* tp_dictoffset */
646 parmpy_init, /* tp_init */
647 0, /* tp_alloc */
648 PyType_GenericNew /* tp_new */
649 };