pidl/python: Use new talloc utility functions.
[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         return unless (defined($d->{ELEMENTS}));
83
84         foreach my $e (@{$d->{ELEMENTS}}) {
85                 $e =~ /^([A-Za-z0-9_]+)=(.*)$/;
86                 my $cname = $1;
87                 
88                 $self->register_constant($cname, $d, $cname);
89         }
90 }
91
92 sub FromUnionToPythonFunction($$$)
93 {
94         my ($self, $type, $switch, $name) = @_;
95
96         $self->pidl("switch ($switch) {");
97         $self->indent;
98
99         foreach my $e (@{$type->{ELEMENTS}}) {
100                 my $conv = $self->ConvertObjectToPython($e->{TYPE}, "$name->$e->{NAME}");
101                 if (defined($e->{CASE})) {
102                         $self->pidl("$e->{CASE}: return $conv;");
103                 } else {
104                         $self->pidl("default: return $conv;");
105                 }
106         }
107
108         $self->deindent;
109         $self->pidl("}");
110
111         $self->pidl("PyErr_SetString(PyExc_TypeError, \"unknown union level\");");
112         $self->pidl("return NULL;");
113 }
114
115 sub FromPythonToUnionFunction($$$$)
116 {
117         my ($self, $type, $switch, $mem_ctx, $name) = @_;
118
119         $self->pidl("switch ($switch) {");
120         $self->indent;
121
122         foreach my $e (@{$type->{ELEMENTS}}) {
123                 my $conv = $self->ConvertObjectFromPython($e->{TYPE}, "$name");
124                 if (defined($e->{CASE})) {
125                         $self->pidl("$e->{CASE}: return $conv;");
126                 } else {
127                         $self->pidl("default: return $conv;");
128                 }
129         }
130
131         $self->deindent;
132         $self->pidl("}");
133         $self->pidl("");
134         $self->pidl("PyErr_SetString(PyExc_TypeError, \"invalid union level value\");");
135         $self->pidl("return NULL;");
136 }
137
138 sub PythonStruct($$$$)
139 {
140         my ($self, $name, $cname, $d) = @_;
141
142         $self->pidl("staticforward PyTypeObject $name\_ObjectType;");
143
144         $self->pidl("");
145
146         $self->pidl("static PyObject *py_$name\_getattr(PyTypeObject *obj, char *name)");
147         $self->pidl("{");
148         $self->indent;
149         $self->pidl("py_talloc_Object *py_object = (py_talloc_Object *)obj;");
150         $self->pidl("$cname *object = py_talloc_get_type(py_object, $cname);");
151         foreach my $e (@{$d->{ELEMENTS}}) {
152                 $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {");
153                 my $varname = "object->$e->{NAME}";
154                 $self->indent;
155                 $self->pidl("return ".$self->ConvertObjectToPython($e->{TYPE}, $varname) . ";");
156                 $self->deindent;
157                 $self->pidl("}");
158         }
159         $self->pidl("PyErr_SetString(PyExc_AttributeError, \"no such attribute\");");
160         $self->pidl("return NULL;");
161         $self->deindent;
162         $self->pidl("}");
163         $self->pidl("");
164
165         $self->pidl("static PyObject *py_$name\_setattr(PyTypeObject *obj, char *name, PyObject *value)");
166         $self->pidl("{");
167         $self->indent;
168         $self->pidl("py_talloc_Object *py_object = (py_talloc_Object *)obj;");
169         $self->pidl("$cname *object = py_talloc_get_type(py_object, $cname);");
170         foreach my $e (@{$d->{ELEMENTS}}) {
171                 $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {");
172                 my $varname = "object->$e->{NAME}";
173                 $self->indent;
174                 $self->pidl("/* FIXME: talloc_free($varname) if necessary */");
175                 $self->pidl("$varname = " . $self->ConvertObjectFromPython($e->{TYPE}, "value") . ";");
176                 $self->deindent;
177                 $self->pidl("}");
178         }
179         $self->pidl("PyErr_SetString(PyExc_AttributeError, \"no such attribute\");");
180         $self->pidl("return NULL;");
181         $self->deindent;
182         $self->pidl("}");
183         $self->pidl("");
184
185         $self->pidl("static PyTypeObject $name\_ObjectType = {");
186         $self->indent;
187         $self->pidl("PyObject_HEAD_INIT(NULL) 0,");
188         $self->pidl(".tp_name = \"$name\",");
189         $self->pidl(".tp_basicsize = sizeof(py_talloc_Object),");
190         $self->pidl(".tp_dealloc = (destructor)py_talloc_dealloc,");
191         $self->pidl(".tp_getattr = (getattrfunc)py_$name\_getattr,");
192         $self->pidl(".tp_setattr = (setattrfunc)py_$name\_setattr,");
193         $self->deindent;
194         $self->pidl("};");
195
196         $self->pidl("");
197
198         my $py_fnname = "py_$name";
199         $self->pidl("static PyObject *$py_fnname(PyObject *self, PyObject *args)");
200         $self->pidl("{");
201         $self->indent;
202         $self->pidl("$cname *ret = talloc_zero(NULL, $cname);");
203         $self->pidl("return py_talloc_import(&$name\_ObjectType, ret);");
204         $self->deindent;
205         $self->pidl("}");
206         $self->pidl("");
207
208         return $py_fnname;
209 }
210
211 sub PythonFunction($$$)
212 {
213         my ($self, $fn, $iface) = @_;
214
215         $self->pidl("static PyObject *py_$fn->{NAME}(PyObject *self, PyObject *args)");
216         $self->pidl("{");
217         $self->indent;
218         $self->pidl("$iface\_InterfaceObject *iface = ($iface\_InterfaceObject *)self;");
219         $self->pidl("NTSTATUS status;");
220         $self->pidl("TALLOC_CTX *mem_ctx = talloc_new(NULL);");
221         $self->pidl("struct $fn->{NAME} r;");
222         $self->pidl("PyObject *result;");
223         my $result_size = 0;
224
225         foreach my $e (@{$fn->{ELEMENTS}}) {
226                 if (grep(/in/,@{$e->{DIRECTION}})) {
227                         $self->pidl("PyObject *py_$e->{NAME};");
228                 }
229                 if (grep(/out/,@{$e->{DIRECTION}})) {
230                         $result_size++;
231                 }
232         }
233         if ($result_size > 0) {
234                 $self->pidl("");
235                 $self->pidl("ZERO_STRUCT(r.out);");
236         }
237         if ($fn->{RETURN_TYPE}) {
238                 $result_size++;
239         }
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") {
320                 $self->pidl("PyObject *py_import_$d->{NAME}(" .mapTypeName($d) . " *in)");
321                 $self->pidl("{");
322                 $self->indent;
323                 $self->FromUnionToPythonFunction($actual_ctype, "level", "in") if ($actual_ctype->{TYPE} eq "UNION");
324                 $self->deindent;
325                 $self->pidl("}");
326                 $self->pidl("");
327
328                 $self->pidl(mapTypeName($d) . " *py_export_$d->{NAME}(TALLOC_CTX *mem_ctx, PyObject *in)");
329                 $self->pidl("{");
330                 $self->indent;
331                 $self->FromPythonToUnionFunction($actual_ctype, "level", "mem_ctx", "in") if ($actual_ctype->{TYPE} eq "UNION");
332                 $self->deindent;
333                 $self->pidl("}");
334                 $self->pidl("");
335         }
336 }
337
338 sub Interface($$$)
339 {
340         my($self,$interface,$basename) = @_;
341
342         $self->pidl_hdr("#ifndef _HEADER_PYTHON_$interface->{NAME}\n");
343         $self->pidl_hdr("#define _HEADER_PYTHON_$interface->{NAME}\n\n");
344
345         $self->pidl_hdr("\n");
346
347         $self->Const($_) foreach (@{$interface->{CONSTS}});
348
349         foreach my $d (@{$interface->{TYPES}}) {
350                 next if has_property($d, "nopython");
351
352                 $self->PythonType($d, $interface, $basename);
353         }
354
355         $self->pidl("staticforward PyTypeObject $interface->{NAME}_InterfaceType;");
356         $self->pidl("typedef struct {");
357         $self->indent;
358         $self->pidl("PyObject_HEAD");
359         $self->pidl("struct dcerpc_pipe *pipe;");
360         $self->deindent;
361         $self->pidl("} $interface->{NAME}_InterfaceObject;");
362
363         $self->pidl("");
364
365         foreach my $d (@{$interface->{FUNCTIONS}}) {
366                 next if not defined($d->{OPNUM});
367                 next if has_property($d, "nopython");
368
369                 $self->PythonFunction($d, $interface->{NAME});
370         }
371
372         $self->pidl("static PyMethodDef interface_$interface->{NAME}\_methods[] = {");
373         $self->indent;
374         foreach my $d (@{$interface->{FUNCTIONS}}) {
375                 next if not defined($d->{OPNUM});
376                 next if has_property($d, "nopython");
377
378                 my $fn_name = $d->{NAME};
379
380                 $fn_name =~ s/^$interface->{NAME}_//;
381
382                 $self->pidl("{ \"$fn_name\", (PyCFunction)py_$d->{NAME}, METH_VARARGS|METH_KEYWORDS, NULL },");
383         }
384         $self->pidl("{ NULL, NULL, 0, NULL }");
385         $self->deindent;
386         $self->pidl("};");
387         $self->pidl("");
388
389         $self->pidl("static void interface_$interface->{NAME}_dealloc(PyObject* self)");
390         $self->pidl("{");
391         $self->indent;
392         $self->pidl("$interface->{NAME}_InterfaceObject *interface = ($interface->{NAME}_InterfaceObject *)self;");
393         $self->pidl("talloc_free(interface->pipe);");
394         $self->pidl("PyObject_Del(self);");
395         $self->deindent;
396         $self->pidl("}");
397         $self->pidl("");
398
399         $self->pidl("static PyObject *interface_$interface->{NAME}_getattr(PyTypeObject *obj, char *name)");
400         $self->pidl("{");
401         $self->indent;
402         $self->pidl("return Py_FindMethod(interface_$interface->{NAME}\_methods, (PyObject *)obj, name);");
403         $self->deindent;
404         $self->pidl("}");
405
406         $self->pidl("");
407
408         $self->pidl("static PyTypeObject $interface->{NAME}_InterfaceType = {");
409         $self->indent;
410         $self->pidl("PyObject_HEAD_INIT(NULL) 0,");
411         $self->pidl(".tp_name = \"$interface->{NAME}\",");
412         $self->pidl(".tp_basicsize = sizeof($interface->{NAME}_InterfaceObject),");
413         $self->pidl(".tp_dealloc = (destructor)interface_$interface->{NAME}_dealloc,");
414         $self->pidl(".tp_getattr = (getattrfunc)interface_$interface->{NAME}_getattr,");
415         $self->deindent;
416         $self->pidl("};");
417
418         $self->pidl("");
419
420         $self->register_module_method($interface->{NAME}, "interface_$interface->{NAME}", "METH_VARARGS|METH_KEYWORDS", "NULL");
421         $self->pidl("static PyObject *interface_$interface->{NAME}(PyObject *self, PyObject *args)");
422         $self->pidl("{");
423         $self->indent;
424         $self->pidl("$interface->{NAME}_InterfaceObject *ret;");
425         $self->pidl("const char *binding_string;");
426         $self->pidl("struct cli_credentials *credentials;");
427         $self->pidl("struct loadparm_context *lp_ctx;");
428         $self->pidl("TALLOC_CTX *mem_ctx = NULL;");
429         $self->pidl("NTSTATUS status;");
430         $self->pidl("");
431
432         # FIXME: Arguments: binding string, credentials, loadparm context
433         $self->pidl("ret = PyObject_New($interface->{NAME}_InterfaceObject, &$interface->{NAME}_InterfaceType);");
434         $self->pidl("");
435
436         $self->pidl("status = dcerpc_pipe_connect(NULL, &ret->pipe, binding_string, ");
437         $self->pidl("             &ndr_table_$interface->{NAME}, credentials, NULL, lp_ctx);");
438         $self->handle_ntstatus("status", "NULL", "mem_ctx");
439
440         $self->pidl("return (PyObject *)ret;");
441         $self->deindent;
442         $self->pidl("}");
443         
444         $self->pidl("");
445
446         $self->pidl_hdr("\n");
447         $self->pidl_hdr("#endif /* _HEADER_NDR_$interface->{NAME} */\n");
448 }
449
450 sub register_module_method($$$$$)
451 {
452         my ($self, $fn_name, $pyfn_name, $flags, $doc) = @_;
453
454         push (@{$self->{module_methods}}, [$fn_name, $pyfn_name, $flags, $doc])
455 }
456
457 sub ConvertObjectFromPython($$$)
458 {
459         my ($self, $ctype, $cvar) = @_;
460
461         die("undef type for $cvar") unless(defined($ctype));
462
463         if (ref($ctype) ne "HASH") {
464                 $ctype = getType($ctype);
465         }
466
467         if (ref($ctype) ne "HASH") {
468                 return "FIXME($cvar)";
469         }
470
471         my $actual_ctype = $ctype;
472         if ($ctype->{TYPE} eq "TYPEDEF") {
473                 $actual_ctype = $ctype->{DATA};
474         }
475
476         if ($actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP" or 
477                 $actual_ctype->{TYPE} eq "SCALAR" and (
478                 expandAlias($actual_ctype->{NAME}) =~ /^(uint[0-9]+|hyper|NTTIME|time_t|NTTIME_hyper|NTTIME_1sec|dlong|udlong)$/)) {
479                 return "PyInt_AsLong($cvar)";
480         }
481
482         if ($actual_ctype->{TYPE} eq "STRUCT") {
483                 return "py_talloc_get_type($cvar, " . mapTypeName($ctype) . ")";
484         }
485
486         if ($actual_ctype->{TYPE} eq "UNION") {
487                 return "py_export_$ctype->{NAME}($cvar)";
488         }
489
490         return "FIXME($cvar)";
491 }
492
493 sub ConvertObjectToPython($$$)
494 {
495         my ($self, $ctype, $cvar) = @_;
496
497         if ($cvar =~ /^[0-9]+$/ or $cvar =~ /^0x[0-9a-fA-F]+$/) {
498                 return "PyInt_FromLong($cvar)";
499         }
500
501         die("undef type for $cvar") unless(defined($ctype));
502
503         if ($cvar =~ /^".*"$/) {
504                 return "PyString_FromString($cvar)";
505         }
506
507         if (ref($ctype) ne "HASH") {
508                 if (not hasType($ctype)) {
509                         if (ref($ctype) eq "HASH") {
510                                 return "py_import_$ctype->{TYPE}_$ctype->{NAME}($cvar)";
511                         } else {
512                                 return "py_import_$ctype($cvar)"; # best bet
513                         }
514                 }
515
516                 $ctype = getType($ctype);
517         }
518
519         my $actual_ctype = $ctype;
520         if ($ctype->{TYPE} eq "TYPEDEF") {
521                 $actual_ctype = $ctype->{DATA};
522         }
523
524         if ($actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP" or 
525                 ($actual_ctype->{TYPE} eq "SCALAR" and 
526                 expandAlias($actual_ctype->{NAME}) =~ /^(int|long|char|u?int[0-9]+|hyper|dlong|udlong|udlongr|time_t|NTTIME_hyper|NTTIME|NTTIME_1sec)$/)) {
527                 return "PyInt_FromLong($cvar)";
528         }
529
530         if ($ctype->{TYPE} eq "TYPEDEF" and $actual_ctype->{TYPE} eq "UNION") {
531                 return "py_import_$ctype->{NAME}($cvar)";
532         }
533
534         if ($ctype->{TYPE} eq "TYPEDEF" and $actual_ctype->{TYPE} eq "STRUCT") {
535                 # FIXME: if $cvar is not a pointer, do a talloc_dup()
536                 return "py_talloc_import(&$ctype->{NAME}_ObjectType, $cvar)";
537         }
538
539         if ($actual_ctype->{TYPE} eq "SCALAR" and 
540                 expandAlias($actual_ctype->{NAME}) eq "DATA_BLOB") {
541                 return "PyString_FromStringAndSize($cvar->data, $cvar->length)";
542         }
543
544         if ($ctype->{TYPE} eq "STRUCT" or $ctype->{TYPE} eq "UNION") {
545                 return "py_import_$ctype->{TYPE}_$ctype->{NAME}($cvar)";
546         }
547
548         if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "NTSTATUS") {
549                 return "PyInt_FromLong($cvar->v)";
550         }
551
552         if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "WERROR") {
553                 return "PyInt_FromLong($cvar->v)";
554         }
555
556         if ($actual_ctype->{TYPE} eq "SCALAR" and 
557                 ($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")) {
558                 return "PyString_FromString($cvar)";
559         }
560
561         if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "string_array") {
562                 return "FIXME($cvar)";
563         }
564
565         if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "ipv4address") {
566                 return "FIXME($cvar)";
567                 }
568
569         if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "pointer") {
570                 return "PyCObject_FromVoidPtr($cvar, talloc_free)";
571         }
572
573
574         die("unknown type ".mapTypeName($ctype) . ": $cvar");
575 }
576
577 sub Parse($$$$$)
578 {
579     my($self,$basename,$ndr,$ndr_hdr,$hdr) = @_;
580     
581     my $py_hdr = $hdr;
582     $py_hdr =~ s/ndr_([^\/]+)$/py_$1/g;
583
584     $self->pidl_hdr("/* header auto-generated by pidl */\n\n");
585         
586     $self->pidl("
587 /* Python wrapper functions auto-generated by pidl */
588 #include \"includes.h\"
589 #include <Python.h>
590 #include \"librpc/rpc/dcerpc.h\"
591 #include \"scripting/python/pytalloc.h\"
592 #include \"$hdr\"
593 #include \"$ndr_hdr\"
594 #include \"$py_hdr\"
595
596 ");
597
598         foreach my $x (@$ndr) {
599             ($x->{TYPE} eq "INTERFACE") && $self->Interface($x, $basename);
600                 ($x->{TYPE} eq "IMPORT") && $self->Import(@{$x->{PATHS}});
601         }
602         
603         $self->pidl("static PyMethodDef $basename\_methods[] = {");
604         $self->indent;
605         foreach (@{$self->{module_methods}}) {
606                 my ($fn_name, $pyfn_name, $flags, $doc) = @$_;
607                 $self->pidl("{ \"$fn_name\", (PyCFunction)$pyfn_name, $flags, $doc },");
608         }
609         
610         $self->pidl("{ NULL, NULL, 0, NULL }");
611         $self->deindent;
612         $self->pidl("};");
613
614         $self->pidl("");
615
616         $self->pidl("void init$basename(void)");
617         $self->pidl("{");
618         $self->indent;
619         $self->pidl("PyObject *m;");
620         $self->pidl("m = Py_InitModule(\"$basename\", $basename\_methods);");
621         foreach (keys %{$self->{constants}}) {
622                 # FIXME: Handle non-string constants
623                 $self->pidl("PyModule_AddObject(m, \"$_\", " .  $self->ConvertObjectToPython($self->{constants}->{$_}->[0], $self->{constants}->{$_}->[1]) . ");");
624         }
625         $self->deindent;
626         $self->pidl("}");
627     return ($self->{res_hdr}, $self->{res});
628 }
629
630 1;