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