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