OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.2/] [gdb/] [python/] [py-param.c] - Blame information for rev 330

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* 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
 
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
 
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
 
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
 
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
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.