pidl/python: Fix const type wrapping.
[ira/wip.git] / source / pidl / lib / Parse / Pidl / Samba4 / Python.pm
1 ###################################################
2 # Python function wrapper generator
3 # Copyright jelmer@samba.org 2007-2008
4 # released under the GNU GPL
5
6 package Parse::Pidl::Samba4::Python;
7
8 use Exporter;
9 @ISA = qw(Exporter);
10
11 use strict;
12 use Parse::Pidl::Typelist qw(hasType getType mapTypeName expandAlias);
13 use Parse::Pidl::Util qw(has_property ParseExpr);
14 use Parse::Pidl::CUtil qw(get_value_of get_pointer_to);
15
16 use vars qw($VERSION);
17 $VERSION = '0.01';
18
19 sub new($) {
20         my ($class) = @_;
21         my $self = { res => "", res_hdr => "", tabs => "", constants => {},
22                      module_methods => []};
23         bless($self, $class);
24 }
25
26 sub pidl_hdr ($$)
27 {
28         my $self = shift;
29         $self->{res_hdr} .= shift;
30 }
31
32 sub pidl($$)
33 {
34         my ($self, $d) = @_;
35         if ($d) {
36                 $self->{res} .= $self->{tabs};
37                 $self->{res} .= $d;
38         }
39         $self->{res} .= "\n";
40 }
41
42 sub indent($)
43 {
44         my ($self) = @_;
45         $self->{tabs} .= "\t";
46 }
47
48 sub deindent($)
49 {
50         my ($self) = @_;
51         $self->{tabs} = substr($self->{tabs}, 0, -1);
52 }
53
54 sub Import
55 {
56         my $self = shift;
57         my @imports = @_;
58         foreach (@imports) {
59                 s/\.idl\"$//;
60                 s/^\"//;
61                 $self->pidl_hdr("#include \"librpc/gen_ndr/py_$_\.h\"\n");
62         }
63 }
64
65 sub Const($$)
66 {
67     my ($self, $const) = @_;
68         $self->register_constant($const->{NAME}, $const->{DTYPE}, $const->{VALUE});
69 }
70
71 sub register_constant($$$$)
72 {
73         my ($self, $name, $type, $value) = @_;
74
75         $self->{constants}->{$name} = [$type, $value];
76 }
77
78 sub EnumAndBitmapConsts($$$)
79 {
80         my ($self, $name, $d) = @_;
81
82         foreach my $e (@{$d->{ELEMENTS}}) {
83                 $e =~ /^([A-Za-z0-9_]+)=(.*)$/;
84                 my $cname = $1;
85                 
86                 $self->register_constant($cname, $d, $cname);
87         }
88 }
89
90 sub FromUnionToPythonFunction($$)
91 {
92         my ($self, $type) = @_;
93
94         #FIXME
95
96         $self->pidl("return NULL;");
97 }
98
99 sub FromStructToPythonFunction($$)
100 {
101         my ($self, $type) = @_;
102
103         #FIXME
104         $self->pidl("return NULL;");
105 }
106
107 sub FromPythonToUnionFunction($$)
108 {
109         my ($self, $type) = @_;
110
111         #FIXME
112         $self->pidl("return NULL;");
113 }
114
115 sub FromPythonToStructFunction($$)
116 {
117         my ($self, $type) = @_;
118
119         #FIXME
120         $self->pidl("return NULL;");
121 }
122
123 sub PythonStruct($$$$)
124 {
125         my ($self, $name, $cname, $d) = @_;
126
127         $self->pidl("staticforward PyTypeObject $name\_ObjectType;");
128         $self->pidl("typedef struct {");
129         $self->indent;
130         $self->pidl("PyObject_HEAD");
131         $self->pidl("$cname *object;");
132         $self->deindent;
133         $self->pidl("} $name\_Object;");
134
135         $self->pidl("");
136
137         $self->pidl("static PyObject *py_$name\_getattr(PyTypeObject *obj, char *name)");
138         $self->pidl("{");
139         $self->indent;
140         $self->pidl("$name\_Object *py_object = ($name\_Object *)obj;");
141         $self->pidl("$cname *object = talloc_get_type(py_object->object, $cname);");
142         foreach my $e (@{$d->{ELEMENTS}}) {
143                 $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {");
144                 my $varname = "object->$e->{NAME}";
145                 $self->indent;
146                 $self->pidl("return ".$self->ConvertObjectToPython($e->{TYPE}, $varname) . ";");
147                 $self->deindent;
148                 $self->pidl("}");
149         }
150         $self->pidl("PyErr_SetString(PyExc_AttributeError, \"no such attribute\");");
151         $self->pidl("return NULL;");
152         $self->deindent;
153         $self->pidl("}");
154         $self->pidl("");
155
156         $self->pidl("static void py_$name\_dealloc(PyObject* self)");
157         $self->pidl("{");
158         $self->indent;
159         $self->pidl("$name\_Object *obj = ($name\_Object *)self;");
160         $self->pidl("talloc_free(obj->object);");
161         $self->pidl("PyObject_Del(self);");
162         $self->deindent;
163         $self->pidl("}");
164         $self->pidl("");
165
166         $self->pidl("static PyObject *py_$name\_setattr(PyTypeObject *obj, char *name, PyObject *value)");
167         $self->pidl("{");
168         $self->indent;
169         $self->pidl("$name\_Object *py_object = ($name\_Object *)obj;");
170         $self->pidl("$cname *object = talloc_get_type(py_object->object, $cname);");
171         foreach my $e (@{$d->{ELEMENTS}}) {
172                 $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {");
173                 my $varname = "object->$e->{NAME}";
174                 $self->indent;
175                 $self->pidl("/* FIXME: talloc_free($varname) if necessary */");
176                 $self->pidl("$varname = " . $self->ConvertObjectFromPython($e->{TYPE}, "value") . ";");
177                 $self->deindent;
178                 $self->pidl("}");
179         }
180         $self->pidl("PyErr_SetString(PyExc_AttributeError, \"no such attribute\");");
181         $self->pidl("return NULL;");
182         $self->deindent;
183         $self->pidl("}");
184         $self->pidl("");
185
186         $self->pidl("static PyTypeObject $name\_ObjectType = {");
187         $self->indent;
188         $self->pidl("PyObject_HEAD_INIT(NULL) 0,");
189         $self->pidl(".tp_name = \"$name\",");
190         $self->pidl(".tp_basicsize = sizeof($name\_Object),");
191         $self->pidl(".tp_dealloc = (destructor)py_$name\_dealloc,");
192         $self->pidl(".tp_getattr = (getattrfunc)py_$name\_getattr,");
193         $self->pidl(".tp_setattr = (setattrfunc)py_$name\_setattr,");
194         $self->deindent;
195         $self->pidl("};");
196
197         $self->pidl("");
198
199         my $py_fnname = "py_$name";
200         $self->pidl("static PyObject *$py_fnname(PyObject *self, PyObject *args)");
201         $self->pidl("{");
202         $self->indent;
203         $self->pidl("$name\_Object *ret;");
204         $self->pidl("ret = PyObject_New($name\_Object, &$name\_ObjectType);");
205         $self->pidl("return (PyObject *) ret;");
206         $self->deindent;
207         $self->pidl("}");
208         $self->pidl("");
209
210         return $py_fnname;
211 }
212
213 sub PythonFunction($$$)
214 {
215         my ($self, $fn, $iface) = @_;
216
217         $self->pidl("static PyObject *py_$fn->{NAME}(PyObject *self, PyObject *args)");
218         $self->pidl("{");
219         $self->indent;
220         $self->pidl("$iface\_InterfaceObject *iface = ($iface\_InterfaceObject *)self;");
221         $self->pidl("NTSTATUS status;");
222         $self->pidl("TALLOC_CTX *mem_ctx = talloc_new(NULL);");
223         $self->pidl("struct dcerpc_$fn->{NAME} r;");
224         $self->pidl("PyObject *result;");
225         my $result_size = 0;
226
227         foreach my $e (@{$fn->{ELEMENTS}}) {
228                 if (grep(/in/,@{$e->{DIRECTION}})) {
229                         $self->pidl("PyObject *py_$e->{NAME};");
230                 }
231                 if (grep(/out/,@{$e->{DIRECTION}})) {
232                         $result_size++;
233                 }
234         }
235         if ($fn->{RETURN_TYPE}) {
236                 $result_size++;
237         }
238         $self->pidl("");
239         $self->pidl("ZERO_STRUCT(r.out);");
240
241         foreach my $e (@{$fn->{ELEMENTS}}) {
242                 if (grep(/in/,@{$e->{DIRECTION}})) {
243                         $self->pidl("r.in.$e->{NAME} = " . $self->ConvertObjectFromPython($e->{TYPE}, "py_$e->{NAME}") . ";");
244                 }
245         }
246         $self->pidl("status = dcerpc_$fn->{NAME}(iface->pipe, mem_ctx, &r);");
247         $self->handle_ntstatus("status", "NULL", "mem_ctx");
248
249         $self->pidl("result = PyTuple_New($result_size);");
250
251         my $i = 0;
252
253         foreach my $e (@{$fn->{ELEMENTS}}) {
254                 if (grep(/out/,@{$e->{DIRECTION}})) {
255                         $self->pidl("PyTuple_SetItem(result, $i, " . $self->ConvertObjectToPython($e->{TYPE}, "r.out.$e->{NAME}") . ");");
256
257                         $i++;
258                 }
259         }
260
261         if (defined($fn->{RETURN_TYPE})) {
262                 $self->pidl("PyTuple_SetItem(result, $i, " . $self->ConvertObjectToPython($fn->{RETURN_TYPE}, "r.out.result") . ");");
263         }
264
265         $self->pidl("talloc_free(mem_ctx);");
266         $self->pidl("return result;");
267         $self->deindent;
268         $self->pidl("}");
269         $self->pidl("");
270 }
271
272 sub handle_ntstatus($$$$)
273 {
274         my ($self, $var, $retval, $mem_ctx) = @_;
275
276         $self->pidl("if (NT_STATUS_IS_ERR($var)) {");
277         $self->indent;
278         $self->pidl("PyErr_SetString(PyExc_RuntimeError, nt_errstr($var));");
279         $self->pidl("talloc_free($mem_ctx);") if ($mem_ctx);
280         $self->pidl("return $retval;");
281         $self->deindent;
282         $self->pidl("}");
283         $self->pidl("");
284 }
285
286 sub PythonType($$$)
287 {
288         my ($self, $d, $interface, $basename) = @_;
289
290         my $actual_ctype = $d;
291         if ($actual_ctype->{TYPE} eq "TYPEDEF") {
292                 $actual_ctype = $actual_ctype->{DATA};
293         }
294
295         if ($actual_ctype->{TYPE} eq "STRUCT") {
296                 my $py_fnname;
297                 if ($d->{TYPE} eq "STRUCT") {
298                         $py_fnname = $self->PythonStruct($d->{NAME}, mapTypeName($d), $d);
299                 } else {
300                         $py_fnname = $self->PythonStruct($d->{NAME}, mapTypeName($d), $d->{DATA});
301                 }
302
303                 my $fn_name = $d->{NAME};
304
305                 $fn_name =~ s/^$interface->{NAME}_//;
306                 $fn_name =~ s/^$basename\_//;
307
308                 $self->register_module_method($fn_name, $py_fnname, "METH_VARARGS|METH_KEYWORDS", "NULL");
309         }
310
311         if ($d->{TYPE} eq "ENUM" or $d->{TYPE} eq "BITMAP") {
312                 $self->EnumAndBitmapConsts($d->{NAME}, $d);
313         }
314
315         if ($d->{TYPE} eq "TYPEDEF" and ($d->{DATA}->{TYPE} eq "ENUM" or $d->{DATA}->{TYPE} eq "BITMAP")) {
316                 $self->EnumAndBitmapConsts($d->{NAME}, $d->{DATA});
317         }
318
319         if ($actual_ctype->{TYPE} eq "UNION" or $actual_ctype->{TYPE} eq "STRUCT") {
320                 $self->pidl("PyObject *py_import_$d->{NAME}(" .mapTypeName($d) . " *in)");
321                 $self->pidl("{");
322                 $self->indent;
323                 $self->FromStructToPythonFunction($d) if ($actual_ctype->{TYPE} eq "STRUCT");
324                 $self->FromUnionToPythonFunction($d) if ($actual_ctype->{TYPE} eq "UNION");
325                 $self->deindent;
326                 $self->pidl("}");
327                 $self->pidl("");
328
329                 $self->pidl(mapTypeName($d) . " *py_export_$d->{NAME}(TALLOC_CTX *mem_ctx, PyObject *in)");
330                 $self->pidl("{");
331                 $self->indent;
332                 $self->FromPythonToStructFunction($d) if ($actual_ctype->{TYPE} eq "STRUCT");
333                 $self->FromPythonToUnionFunction($d) if ($actual_ctype->{TYPE} eq "UNION");
334                 $self->deindent;
335                 $self->pidl("}");
336                 $self->pidl("");
337         }
338 }
339
340 sub Interface($$$)
341 {
342         my($self,$interface,$basename) = @_;
343
344         $self->pidl_hdr("#ifndef _HEADER_PYTHON_$interface->{NAME}\n");
345         $self->pidl_hdr("#define _HEADER_PYTHON_$interface->{NAME}\n\n");
346
347         $self->pidl_hdr("\n");
348
349         $self->Const($_) foreach (@{$interface->{CONSTS}});
350
351         foreach my $d (@{$interface->{TYPES}}) {
352                 next if has_property($d, "nopython");
353
354                 $self->PythonType($d, $interface, $basename);
355         }
356
357         $self->pidl("staticforward PyTypeObject $interface->{NAME}_InterfaceType;");
358         $self->pidl("typedef struct {");
359         $self->indent;
360         $self->pidl("PyObject_HEAD");
361         $self->pidl("struct dcerpc_pipe *pipe;");
362         $self->deindent;
363         $self->pidl("} $interface->{NAME}_InterfaceObject;");
364
365         $self->pidl("");
366
367         foreach my $d (@{$interface->{FUNCTIONS}}) {
368                 next if not defined($d->{OPNUM});
369                 next if has_property($d, "nopython");
370
371                 $self->PythonFunction($d, $interface->{NAME});
372         }
373
374         $self->pidl("static PyMethodDef interface_$interface->{NAME}\_methods[] = {");
375         $self->indent;
376         foreach my $d (@{$interface->{FUNCTIONS}}) {
377                 next if not defined($d->{OPNUM});
378                 next if has_property($d, "nopython");
379
380                 my $fn_name = $d->{NAME};
381
382                 $fn_name =~ s/^$interface->{NAME}_//;
383
384                 $self->pidl("{ \"$fn_name\", (PyCFunction)py_$d->{NAME}, METH_VARARGS|METH_KEYWORDS, NULL },");
385         }
386         $self->pidl("{ NULL, NULL, 0, NULL }");
387         $self->deindent;
388         $self->pidl("};");
389         $self->pidl("");
390
391         $self->pidl("static void interface_$interface->{NAME}_dealloc(PyObject* self)");
392         $self->pidl("{");
393         $self->indent;
394         $self->pidl("$interface->{NAME}_InterfaceObject *interface = ($interface->{NAME}_InterfaceObject *)self;");
395         $self->pidl("talloc_free(interface->pipe);");
396         $self->pidl("PyObject_Del(self);");
397         $self->deindent;
398         $self->pidl("}");
399         $self->pidl("");
400
401         $self->pidl("static PyObject *interface_$interface->{NAME}_getattr(PyTypeObject *obj, char *name)");
402         $self->pidl("{");
403         $self->indent;
404         $self->pidl("return Py_FindMethod(interface_$interface->{NAME}\_methods, (PyObject *)obj, name);");
405         $self->deindent;
406         $self->pidl("}");
407
408         $self->pidl("");
409
410         $self->pidl("static PyTypeObject $interface->{NAME}_InterfaceType = {");
411         $self->indent;
412         $self->pidl("PyObject_HEAD_INIT(NULL) 0,");
413         $self->pidl(".tp_name = \"$interface->{NAME}\",");
414         $self->pidl(".tp_basicsize = sizeof($interface->{NAME}_InterfaceObject),");
415         $self->pidl(".tp_dealloc = interface_$interface->{NAME}_dealloc,");
416         $self->pidl(".tp_getattr = interface_$interface->{NAME}_getattr,");
417         $self->deindent;
418         $self->pidl("};");
419
420         $self->pidl("");
421
422         $self->register_module_method($interface->{NAME}, "interface_$interface->{NAME}", "METH_VARARGS|METH_KEYWORDS", "NULL");
423         $self->pidl("static PyObject *interface_$interface->{NAME}(PyObject *self, PyObject *args)");
424         $self->pidl("{");
425         $self->indent;
426         $self->pidl("$interface->{NAME}_InterfaceObject *ret;");
427         $self->pidl("const char *binding_string;");
428         $self->pidl("struct cli_credentials *credentials;");
429         $self->pidl("struct loadparm_context *lp_ctx;");
430         $self->pidl("TALLOC_CTX *mem_ctx = NULL;");
431         $self->pidl("NTSTATUS status;");
432         $self->pidl("");
433
434         # FIXME: Arguments: binding string, credentials, loadparm context
435         $self->pidl("ret = PyObject_New($interface->{NAME}_InterfaceObject, &$interface->{NAME}_InterfaceType);");
436         $self->pidl("");
437
438         $self->pidl("status = dcerpc_pipe_connect(NULL, &ret->pipe, binding_string, ");
439         $self->pidl("             &ndr_table_$interface->{NAME}, credentials, NULL, lp_ctx);");
440         $self->handle_ntstatus("status", "NULL", "mem_ctx");
441
442         $self->pidl("return (PyObject *)ret;");
443         $self->deindent;
444         $self->pidl("}");
445         
446         $self->pidl("");
447
448         $self->pidl_hdr("\n");
449         $self->pidl_hdr("#endif /* _HEADER_NDR_$interface->{NAME} */\n");
450 }
451
452 sub register_module_method($$$$$)
453 {
454         my ($self, $fn_name, $pyfn_name, $flags, $doc) = @_;
455
456         push (@{$self->{module_methods}}, [$fn_name, $pyfn_name, $flags, $doc])
457 }
458
459 sub ConvertObjectFromPython($$$)
460 {
461         my ($self, $ctype, $cvar) = @_;
462
463         die("undef type for $cvar") unless(defined($ctype));
464
465         if (ref($ctype) ne "HASH") {
466                 $ctype = getType($ctype);
467         }
468
469         if (ref($ctype) ne "HASH") {
470                 return "FIXME($cvar)";
471         }
472
473         my $actual_ctype = $ctype;
474         if ($ctype->{TYPE} eq "TYPEDEF") {
475                 $actual_ctype = $ctype->{DATA};
476         }
477
478         if ($actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP" or 
479                 $actual_ctype->{TYPE} eq "SCALAR" and (
480                 expandAlias($actual_ctype->{NAME}) =~ /^(uint[0-9]+|hyper|NTTIME|time_t|NTTIME_hyper|NTTIME_1sec|dlong|udlong)$/)) {
481                 return "PyInt_AsLong($cvar)";
482         }
483
484         return "FIXME($cvar)";
485 }
486
487 sub ConvertObjectToPython($$$)
488 {
489         my ($self, $ctype, $cvar) = @_;
490
491         if ($cvar =~ /^[0-9]+$/ or $cvar =~ /^0x[0-9a-fA-F]+$/) {
492                 return "PyInt_FromLong($cvar)";
493         }
494
495         die("undef type for $cvar") unless(defined($ctype));
496
497         if ($cvar =~ /^".*"$/) {
498                 return "PyString_FromString($cvar)";
499         }
500
501         if (ref($ctype) ne "HASH") {
502                 if (not hasType($ctype)) {
503                         if (ref($ctype) eq "HASH") {
504                                 return "py_import_$ctype->{TYPE}_$ctype->{NAME}($cvar)";
505                         } else {
506                                 return "py_import_$ctype($cvar)"; # best bet
507                         }
508                 }
509
510                 $ctype = getType($ctype);
511         }
512
513         my $actual_ctype = $ctype;
514         if ($ctype->{TYPE} eq "TYPEDEF") {
515                 $actual_ctype = $ctype->{DATA};
516         }
517
518         if ($actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP" or 
519                 ($actual_ctype->{TYPE} eq "SCALAR" and 
520                 expandAlias($actual_ctype->{NAME}) =~ /^(int|long|char|u?int[0-9]+|hyper|dlong|udlong|udlongr|time_t|NTTIME_hyper|NTTIME|NTTIME_1sec)$/)) {
521                 return "PyInt_FromLong($cvar)";
522         }
523
524         if ($ctype->{TYPE} eq "TYPEDEF" and (
525                         $actual_ctype->{TYPE} eq "STRUCT" or 
526                         $actual_ctype->{TYPE} eq "UNION")) {
527                 return "py_import_$ctype->{NAME}($cvar)";
528         }
529
530         if ($actual_ctype->{TYPE} eq "SCALAR" and 
531                 expandAlias($actual_ctype->{NAME}) eq "DATA_BLOB") {
532                 return "PyString_FromStringAndSize($cvar->data, $cvar->length)";
533         }
534
535         if ($ctype->{TYPE} eq "STRUCT" or $ctype->{TYPE} eq "UNION") {
536                 return "py_import_$ctype->{TYPE}_$ctype->{NAME}($cvar)";
537         }
538
539         if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "NTSTATUS") {
540                 return "PyInt_FromLong($cvar->v)";
541         }
542
543         if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "WERROR") {
544                 return "PyInt_FromLong($cvar->v)";
545         }
546
547         if ($actual_ctype->{TYPE} eq "SCALAR" and 
548                 ($actual_ctype->{NAME} eq "string" or $actual_ctype->{NAME} eq "nbt_string" or $actual_ctype->{NAME} eq "nbt_name" or $actual_ctype->{NAME} eq "wrepl_nbt_name")) {
549                 return "PyString_FromString($cvar)";
550         }
551
552         if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "string_array") {
553                 return "FIXME($cvar)";
554         }
555
556         if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "ipv4address") {
557                 return "FIXME($cvar)";
558                 }
559
560         if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "pointer") {
561                 return "PyCObject_FromVoidPtr($cvar, talloc_free)";
562         }
563
564
565         die("unknown type ".mapTypeName($ctype) . ": $cvar");
566 }
567
568 sub Parse($$$$)
569 {
570     my($self,$basename,$ndr,$hdr) = @_;
571     
572     my $py_hdr = $hdr;
573     $py_hdr =~ s/ndr_([^\/]+)$/py_$1/g;
574
575     $self->pidl_hdr("/* header auto-generated by pidl */\n\n");
576         
577     $self->pidl("
578 /* Python wrapper functions auto-generated by pidl */
579 #include \"includes.h\"
580 #include <Python.h>
581 #include \"librpc/rpc/dcerpc.h\"
582 #include \"$hdr\"
583 #include \"$py_hdr\"
584
585 ");
586
587         foreach my $x (@$ndr) {
588             ($x->{TYPE} eq "INTERFACE") && $self->Interface($x, $basename);
589                 ($x->{TYPE} eq "IMPORT") && $self->Import(@{$x->{PATHS}});
590         }
591         
592         $self->pidl("static PyMethodDef $basename\_methods[] = {");
593         $self->indent;
594         foreach (@{$self->{module_methods}}) {
595                 my ($fn_name, $pyfn_name, $flags, $doc) = @$_;
596                 $self->pidl("{ \"$fn_name\", (PyCFunction)$pyfn_name, $flags, $doc },");
597         }
598         
599         $self->pidl("{ NULL, NULL, 0, NULL }");
600         $self->deindent;
601         $self->pidl("};");
602
603         $self->pidl("");
604
605         $self->pidl("void init$basename(void)");
606         $self->pidl("{");
607         $self->indent;
608         $self->pidl("PyObject *m;");
609         $self->pidl("m = Py_InitModule(\"$basename\", $basename\_methods);");
610         foreach (keys %{$self->{constants}}) {
611                 # FIXME: Handle non-string constants
612                 $self->pidl("PyModule_AddObject(m, \"$_\", " .  $self->ConvertObjectToPython($self->{constants}->{$_}->[0], $self->{constants}->{$_}->[1]) . ");");
613         }
614         $self->deindent;
615         $self->pidl("}");
616     return ($self->{res_hdr}, $self->{res});
617 }
618
619 1;