]> Git Repo - binutils.git/blob - gdb/python/py-param.c
run copyright.sh for 2011.
[binutils.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 };
This page took 0.063878 seconds and 4 git commands to generate.