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