1/* GDB parameters implemented in Python 2 3 Copyright (C) 2008-2020 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 "python-internal.h" 24#include "charset.h" 25#include "gdbcmd.h" 26#include "cli/cli-decode.h" 27#include "completer.h" 28#include "language.h" 29#include "arch-utils.h" 30 31/* Parameter constants and their values. */ 32struct parm_constant 33{ 34 const char *name; 35 int value; 36}; 37 38struct parm_constant parm_constants[] = 39{ 40 { "PARAM_BOOLEAN", var_boolean }, /* ARI: var_boolean */ 41 { "PARAM_AUTO_BOOLEAN", var_auto_boolean }, 42 { "PARAM_UINTEGER", var_uinteger }, 43 { "PARAM_INTEGER", var_integer }, 44 { "PARAM_STRING", var_string }, 45 { "PARAM_STRING_NOESCAPE", var_string_noescape }, 46 { "PARAM_OPTIONAL_FILENAME", var_optional_filename }, 47 { "PARAM_FILENAME", var_filename }, 48 { "PARAM_ZINTEGER", var_zinteger }, 49 { "PARAM_ZUINTEGER", var_zuinteger }, 50 { "PARAM_ZUINTEGER_UNLIMITED", var_zuinteger_unlimited }, 51 { "PARAM_ENUM", var_enum }, 52 { NULL, 0 } 53}; 54 55/* A union that can hold anything described by enum var_types. */ 56union parmpy_variable 57{ 58 /* Hold a boolean value. */ 59 bool boolval; 60 61 /* Hold an integer value. */ 62 int intval; 63 64 /* Hold an auto_boolean. */ 65 enum auto_boolean autoboolval; 66 67 /* Hold an unsigned integer value, for uinteger. */ 68 unsigned int uintval; 69 70 /* Hold a string, for the various string types. */ 71 char *stringval; 72 73 /* Hold a string, for enums. */ 74 const char *cstringval; 75}; 76 77/* A GDB parameter. */ 78struct parmpy_object 79{ 80 PyObject_HEAD 81 82 /* The type of the parameter. */ 83 enum var_types type; 84 85 /* The value of the parameter. */ 86 union parmpy_variable value; 87 88 /* For an enum command, the possible values. The vector is 89 allocated with xmalloc, as is each element. It is 90 NULL-terminated. */ 91 const char **enumeration; 92}; 93 94typedef struct parmpy_object parmpy_object; 95 96extern PyTypeObject parmpy_object_type 97 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("parmpy_object"); 98 99/* Some handy string constants. */ 100static PyObject *set_doc_cst; 101static PyObject *show_doc_cst; 102 103 104 105/* Get an attribute. */ 106static PyObject * 107get_attr (PyObject *obj, PyObject *attr_name) 108{ 109 if (PyString_Check (attr_name) 110#ifdef IS_PY3K 111 && ! PyUnicode_CompareWithASCIIString (attr_name, "value")) 112#else 113 && ! strcmp (PyString_AsString (attr_name), "value")) 114#endif 115 { 116 parmpy_object *self = (parmpy_object *) obj; 117 118 return gdbpy_parameter_value (self->type, &self->value); 119 } 120 121 return PyObject_GenericGetAttr (obj, attr_name); 122} 123 124/* Set a parameter value from a Python value. Return 0 on success. Returns 125 -1 on error, with a python exception set. */ 126static int 127set_parameter_value (parmpy_object *self, PyObject *value) 128{ 129 int cmp; 130 131 switch (self->type) 132 { 133 case var_string: 134 case var_string_noescape: 135 case var_optional_filename: 136 case var_filename: 137 if (! gdbpy_is_string (value) 138 && (self->type == var_filename 139 || value != Py_None)) 140 { 141 PyErr_SetString (PyExc_RuntimeError, 142 _("String required for filename.")); 143 144 return -1; 145 } 146 if (value == Py_None) 147 { 148 xfree (self->value.stringval); 149 if (self->type == var_optional_filename) 150 self->value.stringval = xstrdup (""); 151 else 152 self->value.stringval = NULL; 153 } 154 else 155 { 156 gdb::unique_xmalloc_ptr<char> 157 string (python_string_to_host_string (value)); 158 if (string == NULL) 159 return -1; 160 161 xfree (self->value.stringval); 162 self->value.stringval = string.release (); 163 } 164 break; 165 166 case var_enum: 167 { 168 int i; 169 170 if (! gdbpy_is_string (value)) 171 { 172 PyErr_SetString (PyExc_RuntimeError, 173 _("ENUM arguments must be a string.")); 174 return -1; 175 } 176 177 gdb::unique_xmalloc_ptr<char> 178 str (python_string_to_host_string (value)); 179 if (str == NULL) 180 return -1; 181 for (i = 0; self->enumeration[i]; ++i) 182 if (! strcmp (self->enumeration[i], str.get ())) 183 break; 184 if (! self->enumeration[i]) 185 { 186 PyErr_SetString (PyExc_RuntimeError, 187 _("The value must be member of an enumeration.")); 188 return -1; 189 } 190 self->value.cstringval = self->enumeration[i]; 191 break; 192 } 193 194 case var_boolean: 195 if (! PyBool_Check (value)) 196 { 197 PyErr_SetString (PyExc_RuntimeError, 198 _("A boolean argument is required.")); 199 return -1; 200 } 201 cmp = PyObject_IsTrue (value); 202 if (cmp < 0) 203 return -1; 204 self->value.boolval = cmp; 205 break; 206 207 case var_auto_boolean: 208 if (! PyBool_Check (value) && value != Py_None) 209 { 210 PyErr_SetString (PyExc_RuntimeError, 211 _("A boolean or None is required")); 212 return -1; 213 } 214 215 if (value == Py_None) 216 self->value.autoboolval = AUTO_BOOLEAN_AUTO; 217 else 218 { 219 cmp = PyObject_IsTrue (value); 220 if (cmp < 0 ) 221 return -1; 222 if (cmp == 1) 223 self->value.autoboolval = AUTO_BOOLEAN_TRUE; 224 else 225 self->value.autoboolval = AUTO_BOOLEAN_FALSE; 226 } 227 break; 228 229 case var_integer: 230 case var_zinteger: 231 case var_uinteger: 232 case var_zuinteger: 233 case var_zuinteger_unlimited: 234 { 235 long l; 236 int ok; 237 238 if (! PyInt_Check (value)) 239 { 240 PyErr_SetString (PyExc_RuntimeError, 241 _("The value must be integer.")); 242 return -1; 243 } 244 245 if (! gdb_py_int_as_long (value, &l)) 246 return -1; 247 248 switch (self->type) 249 { 250 case var_uinteger: 251 if (l == 0) 252 l = UINT_MAX; 253 /* Fall through. */ 254 case var_zuinteger: 255 ok = (l >= 0 && l <= UINT_MAX); 256 break; 257 258 case var_zuinteger_unlimited: 259 ok = (l >= -1 && l <= INT_MAX); 260 break; 261 262 case var_integer: 263 ok = (l >= INT_MIN && l <= INT_MAX); 264 if (l == 0) 265 l = INT_MAX; 266 break; 267 268 case var_zinteger: 269 ok = (l >= INT_MIN && l <= INT_MAX); 270 break; 271 272 default: 273 gdb_assert_not_reached ("unknown var_ constant"); 274 } 275 276 if (! ok) 277 { 278 PyErr_SetString (PyExc_RuntimeError, 279 _("Range exceeded.")); 280 return -1; 281 } 282 283 if (self->type == var_uinteger || self->type == var_zuinteger) 284 self->value.uintval = (unsigned) l; 285 else 286 self->value.intval = (int) l; 287 break; 288 } 289 290 default: 291 PyErr_SetString (PyExc_RuntimeError, 292 _("Unhandled type in parameter value.")); 293 return -1; 294 } 295 296 return 0; 297} 298 299/* Set an attribute. Returns -1 on error, with a python exception set. */ 300static int 301set_attr (PyObject *obj, PyObject *attr_name, PyObject *val) 302{ 303 if (PyString_Check (attr_name) 304#ifdef IS_PY3K 305 && ! PyUnicode_CompareWithASCIIString (attr_name, "value")) 306#else 307 && ! strcmp (PyString_AsString (attr_name), "value")) 308#endif 309 { 310 if (!val) 311 { 312 PyErr_SetString (PyExc_RuntimeError, 313 _("Cannot delete a parameter's value.")); 314 return -1; 315 } 316 return set_parameter_value ((parmpy_object *) obj, val); 317 } 318 319 return PyObject_GenericSetAttr (obj, attr_name, val); 320} 321 322/* A helper function which returns a documentation string for an 323 object. */ 324 325static gdb::unique_xmalloc_ptr<char> 326get_doc_string (PyObject *object, PyObject *attr) 327{ 328 gdb::unique_xmalloc_ptr<char> result; 329 330 if (PyObject_HasAttr (object, attr)) 331 { 332 gdbpy_ref<> ds_obj (PyObject_GetAttr (object, attr)); 333 334 if (ds_obj != NULL && gdbpy_is_string (ds_obj.get ())) 335 { 336 result = python_string_to_host_string (ds_obj.get ()); 337 if (result == NULL) 338 gdbpy_print_stack (); 339 } 340 } 341 if (! result) 342 result.reset (xstrdup (_("This command is not documented."))); 343 return result; 344} 345 346/* Helper function which will execute a METHOD in OBJ passing the 347 argument ARG. ARG can be NULL. METHOD should return a Python 348 string. If this function returns NULL, there has been an error and 349 the appropriate exception set. */ 350static gdb::unique_xmalloc_ptr<char> 351call_doc_function (PyObject *obj, PyObject *method, PyObject *arg) 352{ 353 gdb::unique_xmalloc_ptr<char> data; 354 gdbpy_ref<> result (PyObject_CallMethodObjArgs (obj, method, arg, NULL)); 355 356 if (result == NULL) 357 return NULL; 358 359 if (gdbpy_is_string (result.get ())) 360 { 361 data = python_string_to_host_string (result.get ()); 362 if (! data) 363 return NULL; 364 } 365 else 366 { 367 PyErr_SetString (PyExc_RuntimeError, 368 _("Parameter must return a string value.")); 369 return NULL; 370 } 371 372 return data; 373} 374 375/* A callback function that is registered against the respective 376 add_setshow_* set_doc prototype. This function will either call 377 the Python function "get_set_string" or extract the Python 378 attribute "set_doc" and return the contents as a string. If 379 neither exist, insert a string indicating the Parameter is not 380 documented. */ 381static void 382get_set_value (const char *args, int from_tty, 383 struct cmd_list_element *c) 384{ 385 PyObject *obj = (PyObject *) get_cmd_context (c); 386 gdb::unique_xmalloc_ptr<char> set_doc_string; 387 388 gdbpy_enter enter_py (get_current_arch (), current_language); 389 gdbpy_ref<> set_doc_func (PyString_FromString ("get_set_string")); 390 391 if (set_doc_func == NULL) 392 { 393 gdbpy_print_stack (); 394 return; 395 } 396 397 if (PyObject_HasAttr (obj, set_doc_func.get ())) 398 { 399 set_doc_string = call_doc_function (obj, set_doc_func.get (), NULL); 400 if (! set_doc_string) 401 gdbpy_handle_exception (); 402 } 403 404 const char *str = set_doc_string.get (); 405 if (str != nullptr && str[0] != '\0') 406 fprintf_filtered (gdb_stdout, "%s\n", str); 407} 408 409/* A callback function that is registered against the respective 410 add_setshow_* show_doc prototype. This function will either call 411 the Python function "get_show_string" or extract the Python 412 attribute "show_doc" and return the contents as a string. If 413 neither exist, insert a string indicating the Parameter is not 414 documented. */ 415static void 416get_show_value (struct ui_file *file, int from_tty, 417 struct cmd_list_element *c, 418 const char *value) 419{ 420 PyObject *obj = (PyObject *) get_cmd_context (c); 421 gdb::unique_xmalloc_ptr<char> show_doc_string; 422 423 gdbpy_enter enter_py (get_current_arch (), current_language); 424 gdbpy_ref<> show_doc_func (PyString_FromString ("get_show_string")); 425 426 if (show_doc_func == NULL) 427 { 428 gdbpy_print_stack (); 429 return; 430 } 431 432 if (PyObject_HasAttr (obj, show_doc_func.get ())) 433 { 434 gdbpy_ref<> val_obj (PyString_FromString (value)); 435 436 if (val_obj == NULL) 437 { 438 gdbpy_print_stack (); 439 return; 440 } 441 442 show_doc_string = call_doc_function (obj, show_doc_func.get (), 443 val_obj.get ()); 444 if (! show_doc_string) 445 { 446 gdbpy_print_stack (); 447 return; 448 } 449 450 fprintf_filtered (file, "%s\n", show_doc_string.get ()); 451 } 452 else 453 { 454 /* We have to preserve the existing < GDB 7.3 API. If a 455 callback function does not exist, then attempt to read the 456 show_doc attribute. */ 457 show_doc_string = get_doc_string (obj, show_doc_cst); 458 fprintf_filtered (file, "%s %s\n", show_doc_string.get (), value); 459 } 460} 461 462 463/* A helper function that dispatches to the appropriate add_setshow 464 function. */ 465static void 466add_setshow_generic (int parmclass, enum command_class cmdclass, 467 const char *cmd_name, parmpy_object *self, 468 const char *set_doc, const char *show_doc, 469 const char *help_doc, 470 struct cmd_list_element **set_list, 471 struct cmd_list_element **show_list) 472{ 473 struct cmd_list_element *param = NULL; 474 const char *tmp_name = NULL; 475 476 switch (parmclass) 477 { 478 case var_boolean: 479 480 add_setshow_boolean_cmd (cmd_name, cmdclass, 481 &self->value.boolval, set_doc, show_doc, 482 help_doc, get_set_value, get_show_value, 483 set_list, show_list); 484 485 break; 486 487 case var_auto_boolean: 488 add_setshow_auto_boolean_cmd (cmd_name, cmdclass, 489 &self->value.autoboolval, 490 set_doc, show_doc, help_doc, 491 get_set_value, get_show_value, 492 set_list, show_list); 493 break; 494 495 case var_uinteger: 496 add_setshow_uinteger_cmd (cmd_name, cmdclass, 497 &self->value.uintval, set_doc, show_doc, 498 help_doc, get_set_value, get_show_value, 499 set_list, show_list); 500 break; 501 502 case var_integer: 503 add_setshow_integer_cmd (cmd_name, cmdclass, 504 &self->value.intval, set_doc, show_doc, 505 help_doc, get_set_value, get_show_value, 506 set_list, show_list); break; 507 508 case var_string: 509 add_setshow_string_cmd (cmd_name, cmdclass, 510 &self->value.stringval, set_doc, show_doc, 511 help_doc, get_set_value, get_show_value, 512 set_list, show_list); break; 513 514 case var_string_noescape: 515 add_setshow_string_noescape_cmd (cmd_name, cmdclass, 516 &self->value.stringval, 517 set_doc, show_doc, help_doc, 518 get_set_value, get_show_value, 519 set_list, show_list); 520 521 break; 522 523 case var_optional_filename: 524 add_setshow_optional_filename_cmd (cmd_name, cmdclass, 525 &self->value.stringval, set_doc, 526 show_doc, help_doc, get_set_value, 527 get_show_value, set_list, 528 show_list); 529 break; 530 531 case var_filename: 532 add_setshow_filename_cmd (cmd_name, cmdclass, 533 &self->value.stringval, set_doc, show_doc, 534 help_doc, get_set_value, get_show_value, 535 set_list, show_list); break; 536 537 case var_zinteger: 538 add_setshow_zinteger_cmd (cmd_name, cmdclass, 539 &self->value.intval, set_doc, show_doc, 540 help_doc, get_set_value, get_show_value, 541 set_list, show_list); 542 break; 543 544 case var_zuinteger: 545 add_setshow_zuinteger_cmd (cmd_name, cmdclass, 546 &self->value.uintval, set_doc, show_doc, 547 help_doc, get_set_value, get_show_value, 548 set_list, show_list); 549 break; 550 551 case var_zuinteger_unlimited: 552 add_setshow_zuinteger_unlimited_cmd (cmd_name, cmdclass, 553 &self->value.intval, set_doc, 554 show_doc, help_doc, get_set_value, 555 get_show_value, 556 set_list, show_list); 557 break; 558 559 case var_enum: 560 add_setshow_enum_cmd (cmd_name, cmdclass, self->enumeration, 561 &self->value.cstringval, set_doc, show_doc, 562 help_doc, get_set_value, get_show_value, 563 set_list, show_list); 564 /* Initialize the value, just in case. */ 565 self->value.cstringval = self->enumeration[0]; 566 break; 567 } 568 569 /* Lookup created parameter, and register Python object against the 570 parameter context. Perform this task against both lists. */ 571 tmp_name = cmd_name; 572 param = lookup_cmd (&tmp_name, *show_list, "", NULL, 0, 1); 573 if (param) 574 set_cmd_context (param, self); 575 576 tmp_name = cmd_name; 577 param = lookup_cmd (&tmp_name, *set_list, "", NULL, 0, 1); 578 if (param) 579 set_cmd_context (param, self); 580} 581 582/* A helper which computes enum values. Returns 1 on success. Returns 0 on 583 error, with a python exception set. */ 584static int 585compute_enum_values (parmpy_object *self, PyObject *enum_values) 586{ 587 Py_ssize_t size, i; 588 589 if (! enum_values) 590 { 591 PyErr_SetString (PyExc_RuntimeError, 592 _("An enumeration is required for PARAM_ENUM.")); 593 return 0; 594 } 595 596 if (! PySequence_Check (enum_values)) 597 { 598 PyErr_SetString (PyExc_RuntimeError, 599 _("The enumeration is not a sequence.")); 600 return 0; 601 } 602 603 size = PySequence_Size (enum_values); 604 if (size < 0) 605 return 0; 606 if (size == 0) 607 { 608 PyErr_SetString (PyExc_RuntimeError, 609 _("The enumeration is empty.")); 610 return 0; 611 } 612 613 gdb_argv holder (XCNEWVEC (char *, size + 1)); 614 char **enumeration = holder.get (); 615 616 for (i = 0; i < size; ++i) 617 { 618 gdbpy_ref<> item (PySequence_GetItem (enum_values, i)); 619 620 if (item == NULL) 621 return 0; 622 if (! gdbpy_is_string (item.get ())) 623 { 624 PyErr_SetString (PyExc_RuntimeError, 625 _("The enumeration item not a string.")); 626 return 0; 627 } 628 enumeration[i] = python_string_to_host_string (item.get ()).release (); 629 if (enumeration[i] == NULL) 630 return 0; 631 } 632 633 self->enumeration = const_cast<const char**> (holder.release ()); 634 return 1; 635} 636 637/* Object initializer; sets up gdb-side structures for command. 638 639 Use: __init__(NAME, CMDCLASS, PARMCLASS, [ENUM]) 640 641 NAME is the name of the parameter. It may consist of multiple 642 words, in which case the final word is the name of the new command, 643 and earlier words must be prefix commands. 644 645 CMDCLASS is the kind of command. It should be one of the COMMAND_* 646 constants defined in the gdb module. 647 648 PARMCLASS is the type of the parameter. It should be one of the 649 PARAM_* constants defined in the gdb module. 650 651 If PARMCLASS is PARAM_ENUM, then the final argument should be a 652 collection of strings. These strings are the valid values for this 653 parameter. 654 655 The documentation for the parameter is taken from the doc string 656 for the python class. 657 658 Returns -1 on error, with a python exception set. */ 659 660static int 661parmpy_init (PyObject *self, PyObject *args, PyObject *kwds) 662{ 663 parmpy_object *obj = (parmpy_object *) self; 664 const char *name; 665 gdb::unique_xmalloc_ptr<char> set_doc, show_doc, doc; 666 char *cmd_name; 667 int parmclass, cmdtype; 668 PyObject *enum_values = NULL; 669 struct cmd_list_element **set_list, **show_list; 670 671 if (! PyArg_ParseTuple (args, "sii|O", &name, &cmdtype, &parmclass, 672 &enum_values)) 673 return -1; 674 675 if (cmdtype != no_class && cmdtype != class_run 676 && cmdtype != class_vars && cmdtype != class_stack 677 && cmdtype != class_files && cmdtype != class_support 678 && cmdtype != class_info && cmdtype != class_breakpoint 679 && cmdtype != class_trace && cmdtype != class_obscure 680 && cmdtype != class_maintenance) 681 { 682 PyErr_Format (PyExc_RuntimeError, _("Invalid command class argument.")); 683 return -1; 684 } 685 686 if (parmclass != var_boolean /* ARI: var_boolean */ 687 && parmclass != var_auto_boolean 688 && parmclass != var_uinteger && parmclass != var_integer 689 && parmclass != var_string && parmclass != var_string_noescape 690 && parmclass != var_optional_filename && parmclass != var_filename 691 && parmclass != var_zinteger && parmclass != var_zuinteger 692 && parmclass != var_zuinteger_unlimited && parmclass != var_enum) 693 { 694 PyErr_SetString (PyExc_RuntimeError, 695 _("Invalid parameter class argument.")); 696 return -1; 697 } 698 699 if (enum_values && parmclass != var_enum) 700 { 701 PyErr_SetString (PyExc_RuntimeError, 702 _("Only PARAM_ENUM accepts a fourth argument.")); 703 return -1; 704 } 705 if (parmclass == var_enum) 706 { 707 if (! compute_enum_values (obj, enum_values)) 708 return -1; 709 } 710 else 711 obj->enumeration = NULL; 712 obj->type = (enum var_types) parmclass; 713 memset (&obj->value, 0, sizeof (obj->value)); 714 715 cmd_name = gdbpy_parse_command_name (name, &set_list, 716 &setlist); 717 718 if (! cmd_name) 719 return -1; 720 xfree (cmd_name); 721 cmd_name = gdbpy_parse_command_name (name, &show_list, 722 &showlist); 723 if (! cmd_name) 724 return -1; 725 726 set_doc = get_doc_string (self, set_doc_cst); 727 show_doc = get_doc_string (self, show_doc_cst); 728 doc = get_doc_string (self, gdbpy_doc_cst); 729 730 Py_INCREF (self); 731 732 try 733 { 734 add_setshow_generic (parmclass, (enum command_class) cmdtype, 735 cmd_name, obj, 736 set_doc.get (), show_doc.get (), 737 doc.get (), set_list, show_list); 738 } 739 catch (const gdb_exception &except) 740 { 741 xfree (cmd_name); 742 Py_DECREF (self); 743 gdbpy_convert_exception (except); 744 return -1; 745 } 746 747 return 0; 748} 749 750 751 752/* Initialize the 'parameters' module. */ 753int 754gdbpy_initialize_parameters (void) 755{ 756 int i; 757 758 parmpy_object_type.tp_new = PyType_GenericNew; 759 if (PyType_Ready (&parmpy_object_type) < 0) 760 return -1; 761 762 set_doc_cst = PyString_FromString ("set_doc"); 763 if (! set_doc_cst) 764 return -1; 765 show_doc_cst = PyString_FromString ("show_doc"); 766 if (! show_doc_cst) 767 return -1; 768 769 for (i = 0; parm_constants[i].name; ++i) 770 { 771 if (PyModule_AddIntConstant (gdb_module, 772 parm_constants[i].name, 773 parm_constants[i].value) < 0) 774 return -1; 775 } 776 777 return gdb_pymodule_addobject (gdb_module, "Parameter", 778 (PyObject *) &parmpy_object_type); 779} 780 781 782 783PyTypeObject parmpy_object_type = 784{ 785 PyVarObject_HEAD_INIT (NULL, 0) 786 "gdb.Parameter", /*tp_name*/ 787 sizeof (parmpy_object), /*tp_basicsize*/ 788 0, /*tp_itemsize*/ 789 0, /*tp_dealloc*/ 790 0, /*tp_print*/ 791 0, /*tp_getattr*/ 792 0, /*tp_setattr*/ 793 0, /*tp_compare*/ 794 0, /*tp_repr*/ 795 0, /*tp_as_number*/ 796 0, /*tp_as_sequence*/ 797 0, /*tp_as_mapping*/ 798 0, /*tp_hash */ 799 0, /*tp_call*/ 800 0, /*tp_str*/ 801 get_attr, /*tp_getattro*/ 802 set_attr, /*tp_setattro*/ 803 0, /*tp_as_buffer*/ 804 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 805 "GDB parameter object", /* tp_doc */ 806 0, /* tp_traverse */ 807 0, /* tp_clear */ 808 0, /* tp_richcompare */ 809 0, /* tp_weaklistoffset */ 810 0, /* tp_iter */ 811 0, /* tp_iternext */ 812 0, /* tp_methods */ 813 0, /* tp_members */ 814 0, /* tp_getset */ 815 0, /* tp_base */ 816 0, /* tp_dict */ 817 0, /* tp_descr_get */ 818 0, /* tp_descr_set */ 819 0, /* tp_dictoffset */ 820 parmpy_init, /* tp_init */ 821 0, /* tp_alloc */ 822}; 823