Import gdb 7.3 into vendor branch
[dragonfly.git] / contrib / gdb-7 / gdb / python / py-param.c
1 /* GDB parameters implemented in Python
2
3    Copyright (C) 2008, 2009, 2010, 2011 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       if (! data)
335         return NULL;
336     }
337   else
338     {
339       PyErr_SetString (PyExc_RuntimeError,
340                        _("Parameter must return a string value."));
341       return NULL;
342     }
343
344   return data;
345 }
346
347 /* A callback function that is registered against the respective
348    add_setshow_* set_doc prototype.  This function will either call
349    the Python function "get_set_string" or extract the Python
350    attribute "set_doc" and return the contents as a string.  If
351    neither exist, insert a string indicating the Parameter is not
352    documented.  */
353 static void
354 get_set_value (char *args, int from_tty,
355                struct cmd_list_element *c)
356 {
357   PyObject *obj = (PyObject *) get_cmd_context (c);
358   char *set_doc_string;
359   struct cleanup *cleanup = ensure_python_env (get_current_arch (),
360                                                current_language);
361   PyObject *set_doc_func = PyString_FromString ("get_set_string");
362
363   if (! set_doc_func)
364     goto error;
365
366   make_cleanup_py_decref (set_doc_func);
367
368   if (PyObject_HasAttr (obj, set_doc_func))
369     {
370       set_doc_string = call_doc_function (obj, set_doc_func, NULL);
371       if (! set_doc_string)
372         goto error;
373     }
374   else
375     {
376       /* We have to preserve the existing < GDB 7.3 API.  If a
377          callback function does not exist, then attempt to read the
378          set_doc attribute.  */
379       set_doc_string  = get_doc_string (obj, set_doc_cst);
380     }
381
382   make_cleanup (xfree, set_doc_string);
383   fprintf_filtered (gdb_stdout, "%s\n", set_doc_string);
384
385   do_cleanups (cleanup);
386   return;
387
388  error:
389   gdbpy_print_stack ();
390   do_cleanups (cleanup);
391   return;
392 }
393
394 /* A callback function that is registered against the respective
395    add_setshow_* show_doc prototype.  This function will either call
396    the Python function "get_show_string" or extract the Python
397    attribute "show_doc" and return the contents as a string.  If
398    neither exist, insert a string indicating the Parameter is not
399    documented.  */
400 static void
401 get_show_value (struct ui_file *file, int from_tty,
402                 struct cmd_list_element *c,
403                 const char *value)
404 {
405   PyObject *obj = (PyObject *) get_cmd_context (c);
406   char *show_doc_string = NULL;
407   struct cleanup *cleanup = ensure_python_env (get_current_arch (),
408                                                current_language);
409   PyObject *show_doc_func = PyString_FromString ("get_show_string");
410
411   if (! show_doc_func)
412     goto error;
413
414   make_cleanup_py_decref (show_doc_func);
415
416   if (PyObject_HasAttr (obj, show_doc_func))
417     {
418       PyObject *val_obj = PyString_FromString (value);
419
420       if (! val_obj)
421         goto error;
422
423       make_cleanup_py_decref (val_obj);
424
425       show_doc_string = call_doc_function (obj, show_doc_func, val_obj);
426       if (! show_doc_string)
427         goto error;
428
429       make_cleanup (xfree, show_doc_string);
430
431       fprintf_filtered (file, "%s\n", show_doc_string);
432     }
433   else
434     {
435       /* We have to preserve the existing < GDB 7.3 API.  If a
436          callback function does not exist, then attempt to read the
437          show_doc attribute.  */
438       show_doc_string  = get_doc_string (obj, show_doc_cst);
439       make_cleanup (xfree, show_doc_string);
440       fprintf_filtered (file, "%s %s\n", show_doc_string, value);
441     }
442
443   do_cleanups (cleanup);
444   return;
445
446  error:
447   gdbpy_print_stack ();
448   do_cleanups (cleanup);
449   return;
450 }
451 \f
452
453 /* A helper function that dispatches to the appropriate add_setshow
454    function.  */
455 static void
456 add_setshow_generic (int parmclass, enum command_class cmdclass,
457                      char *cmd_name, parmpy_object *self,
458                      char *set_doc, char *show_doc, char *help_doc,
459                      struct cmd_list_element **set_list,
460                      struct cmd_list_element **show_list)
461 {
462   struct cmd_list_element *param = NULL;
463   char *tmp_name = NULL;
464
465   switch (parmclass)
466     {
467     case var_boolean:
468
469       add_setshow_boolean_cmd (cmd_name, cmdclass,
470                                &self->value.intval, set_doc, show_doc,
471                                help_doc, get_set_value, get_show_value,
472                                set_list, show_list);
473
474       break;
475
476     case var_auto_boolean:
477       add_setshow_auto_boolean_cmd (cmd_name, cmdclass,
478                                     &self->value.autoboolval,
479                                     set_doc, show_doc, help_doc,
480                                     get_set_value, get_show_value,
481                                     set_list, show_list);
482       break;
483
484     case var_uinteger:
485       add_setshow_uinteger_cmd (cmd_name, cmdclass,
486                                 &self->value.uintval, set_doc, show_doc,
487                                 help_doc, get_set_value, get_show_value,
488                                 set_list, show_list);
489       break;
490
491     case var_integer:
492       add_setshow_integer_cmd (cmd_name, cmdclass,
493                                &self->value.intval, set_doc, show_doc,
494                                help_doc, get_set_value, get_show_value,
495                                set_list, show_list); break;
496
497     case var_string:
498       add_setshow_string_cmd (cmd_name, cmdclass,
499                               &self->value.stringval, set_doc, show_doc,
500                               help_doc, get_set_value, get_show_value,
501                               set_list, show_list); break;
502
503     case var_string_noescape:
504       add_setshow_string_noescape_cmd (cmd_name, cmdclass,
505                                        &self->value.stringval,
506                                        set_doc, show_doc, help_doc,
507                                        get_set_value, get_show_value,
508                                        set_list, show_list);
509
510       break;
511
512     case var_optional_filename:
513       add_setshow_optional_filename_cmd (cmd_name, cmdclass,
514                                          &self->value.stringval, set_doc,
515                                          show_doc, help_doc, get_set_value,
516                                          get_show_value, set_list,
517                                          show_list);
518       break;
519
520     case var_filename:
521       add_setshow_filename_cmd (cmd_name, cmdclass,
522                                 &self->value.stringval, set_doc, show_doc,
523                                 help_doc, get_set_value, get_show_value,
524                                 set_list, show_list); break;
525
526     case var_zinteger:
527       add_setshow_zinteger_cmd (cmd_name, cmdclass,
528                                 &self->value.intval, set_doc, show_doc,
529                                 help_doc, get_set_value, get_show_value,
530                                 set_list, show_list);
531       break;
532
533     case var_enum:
534       add_setshow_enum_cmd (cmd_name, cmdclass, self->enumeration,
535                             &self->value.cstringval, set_doc, show_doc,
536                             help_doc, get_set_value, get_show_value,
537                             set_list, show_list);
538       /* Initialize the value, just in case.  */
539       self->value.cstringval = self->enumeration[0];
540       break;
541     }
542
543   /* Lookup created parameter, and register Python object against the
544      parameter context.  Perform this task against both lists.  */
545   tmp_name = cmd_name;
546   param = lookup_cmd (&tmp_name, *show_list, "", 0, 1);
547   if (param)
548     set_cmd_context (param, self);
549
550   tmp_name = cmd_name;
551   param = lookup_cmd (&tmp_name, *set_list, "", 0, 1);
552   if (param)
553     set_cmd_context (param, self);
554 }
555
556 /* A helper which computes enum values.  Returns 1 on success.  Returns 0 on
557    error, with a python exception set.  */
558 static int
559 compute_enum_values (parmpy_object *self, PyObject *enum_values)
560 {
561   Py_ssize_t size, i;
562   struct cleanup *back_to;
563
564   if (! enum_values)
565     {
566       PyErr_SetString (PyExc_RuntimeError,
567                        _("An enumeration is required for PARAM_ENUM."));
568       return 0;
569     }
570
571   if (! PySequence_Check (enum_values))
572     {
573       PyErr_SetString (PyExc_RuntimeError, 
574                        _("The enumeration is not a sequence."));
575       return 0;
576     }
577
578   size = PySequence_Size (enum_values);
579   if (size < 0)
580     return 0;
581   if (size == 0)
582     {
583       PyErr_SetString (PyExc_RuntimeError, 
584                        _("The enumeration is empty."));
585       return 0;
586     }
587
588   self->enumeration = xmalloc ((size + 1) * sizeof (char *));
589   back_to = make_cleanup (free_current_contents, &self->enumeration);
590   memset (self->enumeration, 0, (size + 1) * sizeof (char *));
591
592   for (i = 0; i < size; ++i)
593     {
594       PyObject *item = PySequence_GetItem (enum_values, i);
595
596       if (! item)
597         {
598           do_cleanups (back_to);
599           return 0;
600         }
601       if (! gdbpy_is_string (item))
602         {
603           do_cleanups (back_to);
604           PyErr_SetString (PyExc_RuntimeError, 
605                            _("The enumeration item not a string."));
606           return 0;
607         }
608       self->enumeration[i] = python_string_to_host_string (item);
609       if (self->enumeration[i] == NULL)
610         {
611           do_cleanups (back_to);
612           return 0;
613         }
614       make_cleanup (xfree, (char *) self->enumeration[i]);
615     }
616
617   discard_cleanups (back_to);
618   return 1;
619 }
620
621 /* Object initializer; sets up gdb-side structures for command.
622
623    Use: __init__(NAME, CMDCLASS, PARMCLASS, [ENUM])
624
625    NAME is the name of the parameter.  It may consist of multiple
626    words, in which case the final word is the name of the new command,
627    and earlier words must be prefix commands.
628
629    CMDCLASS is the kind of command.  It should be one of the COMMAND_*
630    constants defined in the gdb module.
631
632    PARMCLASS is the type of the parameter.  It should be one of the
633    PARAM_* constants defined in the gdb module.
634
635    If PARMCLASS is PARAM_ENUM, then the final argument should be a
636    collection of strings.  These strings are the valid values for this
637    parameter.
638
639    The documentation for the parameter is taken from the doc string
640    for the python class.
641
642    Returns -1 on error, with a python exception set.  */
643
644 static int
645 parmpy_init (PyObject *self, PyObject *args, PyObject *kwds)
646 {
647   parmpy_object *obj = (parmpy_object *) self;
648   char *name;
649   char *set_doc, *show_doc, *doc;
650   char *cmd_name;
651   int parmclass, cmdtype;
652   PyObject *enum_values = NULL;
653   struct cmd_list_element **set_list, **show_list;
654   volatile struct gdb_exception except;
655
656   if (! PyArg_ParseTuple (args, "sii|O", &name, &cmdtype, &parmclass,
657                           &enum_values))
658     return -1;
659
660   if (cmdtype != no_class && cmdtype != class_run
661       && cmdtype != class_vars && cmdtype != class_stack
662       && cmdtype != class_files && cmdtype != class_support
663       && cmdtype != class_info && cmdtype != class_breakpoint
664       && cmdtype != class_trace && cmdtype != class_obscure
665       && cmdtype != class_maintenance)
666     {
667       PyErr_Format (PyExc_RuntimeError, _("Invalid command class argument."));
668       return -1;
669     }
670
671   if (parmclass != var_boolean /* ARI: var_boolean */
672       && parmclass != var_auto_boolean
673       && parmclass != var_uinteger && parmclass != var_integer
674       && parmclass != var_string && parmclass != var_string_noescape
675       && parmclass != var_optional_filename && parmclass != var_filename
676       && parmclass != var_zinteger && parmclass != var_enum)
677     {
678       PyErr_SetString (PyExc_RuntimeError,
679                        _("Invalid parameter class argument."));
680       return -1;
681     }
682
683   if (enum_values && parmclass != var_enum)
684     {
685       PyErr_SetString (PyExc_RuntimeError,
686                        _("Only PARAM_ENUM accepts a fourth argument."));
687       return -1;
688     }
689   if (parmclass == var_enum)
690     {
691       if (! compute_enum_values (obj, enum_values))
692         return -1;
693     }
694   else
695     obj->enumeration = NULL;
696   obj->type = (enum var_types) parmclass;
697   memset (&obj->value, 0, sizeof (obj->value));
698
699   cmd_name = gdbpy_parse_command_name (name, &set_list,
700                                        &setlist);
701
702   if (! cmd_name)
703     return -1;
704   xfree (cmd_name);
705   cmd_name = gdbpy_parse_command_name (name, &show_list,
706                                        &showlist);
707   if (! cmd_name)
708     return -1;
709
710   set_doc = get_doc_string (self, set_doc_cst);
711   show_doc = get_doc_string (self, show_doc_cst);
712   doc = get_doc_string (self, gdbpy_doc_cst);
713
714   Py_INCREF (self);
715
716   TRY_CATCH (except, RETURN_MASK_ALL)
717     {
718       add_setshow_generic (parmclass, (enum command_class) cmdtype,
719                            cmd_name, obj,
720                            set_doc, show_doc,
721                            doc, set_list, show_list);
722     }
723   if (except.reason < 0)
724     {
725       xfree (cmd_name);
726       xfree (set_doc);
727       xfree (show_doc);
728       xfree (doc);
729       Py_DECREF (self);
730       PyErr_Format (except.reason == RETURN_QUIT
731                     ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
732                     "%s", except.message);
733       return -1;
734     }
735   return 0;
736 }
737
738 \f
739
740 /* Initialize the 'parameters' module.  */
741 void
742 gdbpy_initialize_parameters (void)
743 {
744   int i;
745
746   if (PyType_Ready (&parmpy_object_type) < 0)
747     return;
748
749   set_doc_cst = PyString_FromString ("set_doc");
750   if (! set_doc_cst)
751     return;
752   show_doc_cst = PyString_FromString ("show_doc");
753   if (! show_doc_cst)
754     return;
755
756   for (i = 0; parm_constants[i].name; ++i)
757     {
758       if (PyModule_AddIntConstant (gdb_module,
759                                    parm_constants[i].name,
760                                    parm_constants[i].value) < 0)
761         return;
762     }
763
764   Py_INCREF (&parmpy_object_type);
765   PyModule_AddObject (gdb_module, "Parameter",
766                       (PyObject *) &parmpy_object_type);
767 }
768
769 \f
770
771 static PyTypeObject parmpy_object_type =
772 {
773   PyObject_HEAD_INIT (NULL)
774   0,                              /*ob_size*/
775   "gdb.Parameter",                /*tp_name*/
776   sizeof (parmpy_object),         /*tp_basicsize*/
777   0,                              /*tp_itemsize*/
778   0,                              /*tp_dealloc*/
779   0,                              /*tp_print*/
780   0,                              /*tp_getattr*/
781   0,                              /*tp_setattr*/
782   0,                              /*tp_compare*/
783   0,                              /*tp_repr*/
784   0,                              /*tp_as_number*/
785   0,                              /*tp_as_sequence*/
786   0,                              /*tp_as_mapping*/
787   0,                              /*tp_hash */
788   0,                              /*tp_call*/
789   0,                              /*tp_str*/
790   get_attr,                       /*tp_getattro*/
791   set_attr,                       /*tp_setattro*/
792   0,                              /*tp_as_buffer*/
793   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
794   "GDB parameter object",         /* tp_doc */
795   0,                              /* tp_traverse */
796   0,                              /* tp_clear */
797   0,                              /* tp_richcompare */
798   0,                              /* tp_weaklistoffset */
799   0,                              /* tp_iter */
800   0,                              /* tp_iternext */
801   0,                              /* tp_methods */
802   0,                              /* tp_members */
803   0,                              /* tp_getset */
804   0,                              /* tp_base */
805   0,                              /* tp_dict */
806   0,                              /* tp_descr_get */
807   0,                              /* tp_descr_set */
808   0,                              /* tp_dictoffset */
809   parmpy_init,                    /* tp_init */
810   0,                              /* tp_alloc */
811   PyType_GenericNew               /* tp_new */
812 };