2010-05-17 Michael Snyder <msnyder@vmware.com>
[platform/upstream/binutils.git] / gdb / python / py-param.c
1 /* GDB parameters implemented in Python
2
3    Copyright (C) 2008, 2009, 2010 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, -1
114    on failure.  */
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 (self->value.stringval)
136         xfree (self->value.stringval);
137       if (value == Py_None)
138         {
139           if (self->type == var_optional_filename)
140             self->value.stringval = xstrdup ("");
141           else
142             self->value.stringval = NULL;
143         }
144       else
145         self->value.stringval = python_string_to_host_string (value);
146       break;
147
148     case var_enum:
149       {
150         int i;
151         char *str;
152
153         if (! gdbpy_is_string (value))
154           {
155             PyErr_SetString (PyExc_RuntimeError, 
156                              _("ENUM arguments must be a string."));
157             return -1;
158           }
159
160         str = python_string_to_host_string (value);
161         for (i = 0; self->enumeration[i]; ++i)
162           if (! strcmp (self->enumeration[i], str))
163             break;
164         xfree (str);
165         if (! self->enumeration[i])
166           {
167             PyErr_SetString (PyExc_RuntimeError,
168                              _("The value must be member of an enumeration."));
169             return -1;
170           }
171         self->value.cstringval = self->enumeration[i];
172         break;
173       }
174
175     case var_boolean:
176       if (! PyBool_Check (value))
177         {
178           PyErr_SetString (PyExc_RuntimeError, 
179                            _("A boolean argument is required."));
180           return -1;
181         }
182       cmp = PyObject_IsTrue (value);
183       if (cmp < 0) 
184           return -1;
185       self->value.intval = cmp;
186       break;
187
188     case var_auto_boolean:
189       if (! PyBool_Check (value) && value != Py_None)
190         {
191           PyErr_SetString (PyExc_RuntimeError,
192                            _("A boolean or None is required"));
193           return -1;
194         }
195
196       if (value == Py_None)
197         self->value.autoboolval = AUTO_BOOLEAN_AUTO;
198       else
199         {
200           cmp = PyObject_IsTrue (value);
201           if (cmp < 0 )
202             return -1;    
203           if (cmp == 1)
204             self->value.autoboolval = AUTO_BOOLEAN_TRUE;
205           else 
206             self->value.autoboolval = AUTO_BOOLEAN_FALSE;
207
208           break;
209         }
210
211     case var_integer:
212     case var_zinteger:
213     case var_uinteger:
214       {
215         long l;
216         int ok;
217
218         if (! PyInt_Check (value))
219           {
220             PyErr_SetString (PyExc_RuntimeError, 
221                              _("The value must be integer."));
222             return -1;
223           }
224
225         l = PyInt_AsLong (value);
226         if (self->type == var_uinteger)
227           {
228             ok = (l >= 0 && l <= UINT_MAX);
229             if (l == 0)
230               l = UINT_MAX;
231           }
232         else if (self->type == var_integer)
233           {
234             ok = (l >= INT_MIN && l <= INT_MAX);
235             if (l == 0)
236               l = INT_MAX;
237           }
238         else
239           ok = (l >= INT_MIN && l <= INT_MAX);
240
241         if (! ok)
242           {
243             PyErr_SetString (PyExc_RuntimeError, 
244                              _("Range exceeded."));
245             return -1;
246           }
247
248         self->value.intval = (int) l;
249         break;
250       }
251
252     default:
253       PyErr_SetString (PyExc_RuntimeError, 
254                        _("Unhandled type in parameter value."));
255       return -1;
256     }
257
258   return 0;
259 }
260
261 /* Set an attribute.  */
262 static int
263 set_attr (PyObject *obj, PyObject *attr_name, PyObject *val)
264 {
265   if (PyString_Check (attr_name)
266       && ! strcmp (PyString_AsString (attr_name), "value"))
267     {
268       if (!val)
269         {
270           PyErr_SetString (PyExc_RuntimeError,
271                            _("Cannot delete a parameter's value."));
272           return -1;
273         }
274       return set_parameter_value ((parmpy_object *) obj, val);
275     }
276
277   return PyObject_GenericSetAttr (obj, attr_name, val);
278 }
279
280 \f
281
282 /* A helper function that dispatches to the appropriate add_setshow
283    function.  */
284 static void
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)
290 {
291   switch (parmclass)
292     {
293     case var_boolean:
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);
297       break;
298
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);
304       break;
305
306     case var_uinteger:
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);
310       break;
311
312     case var_integer:
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);
316       break;
317
318     case var_string:
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);
322       break;
323
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);
329       break;
330
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);
336       break;
337
338     case var_filename:
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);
342       break;
343
344     case var_zinteger:
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);
348       break;
349
350     case var_enum:
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];
357       break;
358     }
359 }
360
361 /* A helper which computes enum values.  Returns 1 on success, 0 on
362    error.  */
363 static int
364 compute_enum_values (parmpy_object *self, PyObject *enum_values)
365 {
366   Py_ssize_t size, i;
367
368   if (! enum_values)
369     {
370       PyErr_SetString (PyExc_RuntimeError,
371                        _("An enumeration is required for PARAM_ENUM."));
372       return 0;
373     }
374
375   if (! PySequence_Check (enum_values))
376     {
377       PyErr_SetString (PyExc_RuntimeError, 
378                        _("The enumeration is not a sequence."));
379       return 0;
380     }
381
382   size = PySequence_Size (enum_values);
383   if (size < 0)
384     return 0;
385   if (size == 0)
386     {
387       PyErr_SetString (PyExc_RuntimeError, 
388                        _("The enumeration is empty."));
389       return 0;
390     }
391
392   self->enumeration = xmalloc ((size + 1) * sizeof (char *));
393   memset (self->enumeration, 0, (size + 1) * sizeof (char *));
394
395   for (i = 0; i < size; ++i)
396     {
397       PyObject *item = PySequence_GetItem (enum_values, i);
398
399       if (! item)
400         return 0;
401       if (! gdbpy_is_string (item))
402         {
403           PyErr_SetString (PyExc_RuntimeError, 
404                            _("The enumeration item not a string."));
405           return 0;
406         }
407       self->enumeration[i] = python_string_to_host_string (item);
408     }
409
410   return 1;
411 }
412
413 /* A helper function which returns a documentation string for an
414    object.  */
415 static char *
416 get_doc_string (PyObject *object, PyObject *attr)
417 {
418   char *result = NULL;
419
420   if (PyObject_HasAttr (object, attr))
421     {
422       PyObject *ds_obj = PyObject_GetAttr (object, attr);
423
424       if (ds_obj && gdbpy_is_string (ds_obj))
425         result = python_string_to_host_string (ds_obj);
426     }
427   if (! result)
428     result = xstrdup (_("This command is not documented."));
429   return result;
430 }
431
432 /* Object initializer; sets up gdb-side structures for command.
433
434    Use: __init__(NAME, CMDCLASS, PARMCLASS, [ENUM])
435
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.
439
440    CMDCLASS is the kind of command.  It should be one of the COMMAND_*
441    constants defined in the gdb module.
442
443    PARMCLASS is the type of the parameter.  It should be one of the
444    PARAM_* constants defined in the gdb module.
445
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
448    parameter.
449
450    The documentation for the parameter is taken from the doc string
451    for the python class.
452    
453 */
454 static int
455 parmpy_init (PyObject *self, PyObject *args, PyObject *kwds)
456 {
457   parmpy_object *obj = (parmpy_object *) self;
458   char *name;
459   char *set_doc, *show_doc, *doc;
460   char *cmd_name;
461   int parmclass, cmdtype;
462   PyObject *enum_values = NULL;
463   struct cmd_list_element **set_list, **show_list;
464   volatile struct gdb_exception except;
465
466   if (! PyArg_ParseTuple (args, "sii|O", &name, &cmdtype, &parmclass,
467                           &enum_values))
468     return -1;
469
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)
476     {
477       PyErr_Format (PyExc_RuntimeError, _("Invalid command class argument."));
478       return -1;
479     }
480
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)
487     {
488       PyErr_SetString (PyExc_RuntimeError, _("Invalid parameter class argument."));
489       return -1;
490     }
491
492   if (enum_values && parmclass != var_enum)
493     {
494       PyErr_SetString (PyExc_RuntimeError,
495                        _("Only PARAM_ENUM accepts a fourth argument."));
496       return -1;
497     }
498   if (parmclass == var_enum)
499     {
500       if (! compute_enum_values (obj, enum_values))
501         return -1;
502     }
503   else
504     obj->enumeration = NULL;
505   obj->type = (enum var_types) parmclass;
506   memset (&obj->value, 0, sizeof (obj->value));
507
508   cmd_name = gdbpy_parse_command_name (name, &set_list,
509                                        &setlist);
510
511   if (! cmd_name)
512     return -1;
513   xfree (cmd_name);
514   cmd_name = gdbpy_parse_command_name (name, &show_list,
515                                        &showlist);
516   if (! cmd_name)
517     return -1;
518
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);
522
523   Py_INCREF (self);
524
525   TRY_CATCH (except, RETURN_MASK_ALL)
526     {
527       add_setshow_generic (parmclass, (enum command_class) cmdtype,
528                            cmd_name, obj,
529                            set_doc, show_doc,
530                            doc, set_list, show_list);
531     }
532   if (except.reason < 0)
533     {
534       xfree (cmd_name);
535       xfree (set_doc);
536       xfree (show_doc);
537       xfree (doc);
538       Py_DECREF (self);
539       PyErr_Format (except.reason == RETURN_QUIT
540                     ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
541                     "%s", except.message);
542       return -1;
543     }
544   return 0;
545 }
546
547 \f
548
549 /* Initialize the 'parameters' module.  */
550 void
551 gdbpy_initialize_parameters (void)
552 {
553   int i;
554
555   if (PyType_Ready (&parmpy_object_type) < 0)
556     return;
557
558   set_doc_cst = PyString_FromString ("set_doc");
559   if (! set_doc_cst)
560     return;
561   show_doc_cst = PyString_FromString ("show_doc");
562   if (! show_doc_cst)
563     return;
564
565   for (i = 0; parm_constants[i].name; ++i)
566     {
567       if (PyModule_AddIntConstant (gdb_module,
568                                    parm_constants[i].name,
569                                    parm_constants[i].value) < 0)
570         return;
571     }
572
573   Py_INCREF (&parmpy_object_type);
574   PyModule_AddObject (gdb_module, "Parameter",
575                       (PyObject *) &parmpy_object_type);
576 }
577
578 \f
579
580 static PyTypeObject parmpy_object_type =
581 {
582   PyObject_HEAD_INIT (NULL)
583   0,                              /*ob_size*/
584   "gdb.Parameter",                /*tp_name*/
585   sizeof (parmpy_object),         /*tp_basicsize*/
586   0,                              /*tp_itemsize*/
587   0,                              /*tp_dealloc*/
588   0,                              /*tp_print*/
589   0,                              /*tp_getattr*/
590   0,                              /*tp_setattr*/
591   0,                              /*tp_compare*/
592   0,                              /*tp_repr*/
593   0,                              /*tp_as_number*/
594   0,                              /*tp_as_sequence*/
595   0,                              /*tp_as_mapping*/
596   0,                              /*tp_hash */
597   0,                              /*tp_call*/
598   0,                              /*tp_str*/
599   get_attr,                       /*tp_getattro*/
600   set_attr,                       /*tp_setattro*/
601   0,                              /*tp_as_buffer*/
602   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
603   "GDB parameter object",         /* tp_doc */
604   0,                              /* tp_traverse */
605   0,                              /* tp_clear */
606   0,                              /* tp_richcompare */
607   0,                              /* tp_weaklistoffset */
608   0,                              /* tp_iter */
609   0,                              /* tp_iternext */
610   0,                              /* tp_methods */
611   0,                              /* tp_members */
612   0,                              /* tp_getset */
613   0,                              /* tp_base */
614   0,                              /* tp_dict */
615   0,                              /* tp_descr_get */
616   0,                              /* tp_descr_set */
617   0,                              /* tp_dictoffset */
618   parmpy_init,                    /* tp_init */
619   0,                              /* tp_alloc */
620   PyType_GenericNew               /* tp_new */
621 };