pidl/python: Fix more warnings in the generated code.
[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, $name) = @_;
95
96         #FIXME
97
98         $self->pidl("return NULL;");
99 }
100
101 sub FromStructToPythonFunction($$$)
102 {
103         my ($self, $type, $name) = @_;
104
105         $self->pidl("$type->{NAME}\_Object *ret;");
106         $self->pidl("ret = PyObject_New($type->{NAME}\_Object, &$type->{NAME}\_ObjectType);");
107         $self->pidl("ret->object = talloc_reference(NULL, $name);");
108         $self->pidl("return (PyObject *) ret;");
109 }
110
111 sub FromPythonToUnionFunction($$$$)
112 {
113         my ($self, $type, $mem_ctx, $name) = @_;
114
115         #FIXME
116         $self->pidl("return NULL;");
117 }
118
119 sub FromPythonToStructFunction($$$$)
120 {
121         my ($self, $type, $mem_ctx, $name) = @_;
122
123         $self->pidl("$type->{NAME}\_Object *py_object = ($type->{NAME}_Object *)$name;");
124         $self->pidl("return talloc_reference($mem_ctx, py_object->object);");
125 }
126
127 sub PythonStruct($$$$)
128 {
129         my ($self, $name, $cname, $d) = @_;
130
131         $self->pidl("staticforward PyTypeObject $name\_ObjectType;");
132         $self->pidl("typedef struct {");
133         $self->indent;
134         $self->pidl("PyObject_HEAD");
135         $self->pidl("$cname *object;");
136         $self->deindent;
137         $self->pidl("} $name\_Object;");
138
139         $self->pidl("");
140
141         $self->pidl("static PyObject *py_$name\_getattr(PyTypeObject *obj, char *name)");
142         $self->pidl("{");
143         $self->indent;
144         $self->pidl("$name\_Object *py_object = ($name\_Object *)obj;");
145         $self->pidl("$cname *object = talloc_get_type(py_object->object, $cname);");
146         foreach my $e (@{$d->{ELEMENTS}}) {
147                 $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {");
148                 my $varname = "object->$e->{NAME}";
149                 $self->indent;
150                 $self->pidl("return ".$self->ConvertObjectToPython($e->{TYPE}, $varname) . ";");
151                 $self->deindent;
152                 $self->pidl("}");
153         }
154         $self->pidl("PyErr_SetString(PyExc_AttributeError, \"no such attribute\");");
155         $self->pidl("return NULL;");
156         $self->deindent;
157         $self->pidl("}");
158         $self->pidl("");
159
160         $self->pidl("static void py_$name\_dealloc(PyObject* self)");
161         $self->pidl("{");
162         $self->indent;
163         $self->pidl("$name\_Object *obj = ($name\_Object *)self;");
164         $self->pidl("talloc_free(obj->object);");
165         $self->pidl("PyObject_Del(self);");
166         $self->deindent;
167         $self->pidl("}");
168         $self->pidl("");
169
170         $self->pidl("static PyObject *py_$name\_setattr(PyTypeObject *obj, char *name, PyObject *value)");
171         $self->pidl("{");
172         $self->indent;
173         $self->pidl("$name\_Object *py_object = ($name\_Object *)obj;");
174         $self->pidl("$cname *object = talloc_get_type(py_object->object, $cname);");
175         foreach my $e (@{$d->{ELEMENTS}}) {
176                 $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {");
177                 my $varname = "object->$e->{NAME}";
178                 $self->indent;
179                 $self->pidl("/* FIXME: talloc_free($varname) if necessary */");
180                 $self->pidl("$varname = " . $self->ConvertObjectFromPython($e->{TYPE}, "value") . ";");
181                 $self->deindent;
182                 $self->pidl("}");
183         }
184         $self->pidl("PyErr_SetString(PyExc_AttributeError, \"no such attribute\");");
185         $self->pidl("return NULL;");
186         $self->deindent;
187         $self->pidl("}");
188         $self->pidl("");
189
190         $self->pidl("static PyTypeObject $name\_ObjectType = {");
191         $self->indent;
192         $self->pidl("PyObject_HEAD_INIT(NULL) 0,");
193         $self->pidl(".tp_name = \"$name\",");
194         $self->pidl(".tp_basicsize = sizeof($name\_Object),");
195         $self->pidl(".tp_dealloc = (destructor)py_$name\_dealloc,");
196         $self->pidl(".tp_getattr = (getattrfunc)py_$name\_getattr,");
197         $self->pidl(".tp_setattr = (setattrfunc)py_$name\_setattr,");
198         $self->deindent;
199         $self->pidl("};");
200
201         $self->pidl("");
202
203         my $py_fnname = "py_$name";
204         $self->pidl("static PyObject *$py_fnname(PyObject *self, PyObject *args)");
205         $self->pidl("{");
206         $self->indent;
207         $self->pidl("$name\_Object *ret;");
208         $self->pidl("ret = PyObject_New($name\_Object, &$name\_ObjectType);");
209         $self->pidl("return (PyObject *) ret;");
210         $self->deindent;
211         $self->pidl("}");
212         $self->pidl("");
213
214         return $py_fnname;
215 }
216
217 sub PythonFunction($$$)
218 {
219         my ($self, $fn, $iface) = @_;
220
221         $self->pidl("static PyObject *py_$fn->{NAME}(PyObject *self, PyObject *args)");
222         $self->pidl("{");
223         $self->indent;
224         $self->pidl("$iface\_InterfaceObject *iface = ($iface\_InterfaceObject *)self;");
225         $self->pidl("NTSTATUS status;");
226         $self->pidl("TALLOC_CTX *mem_ctx = talloc_new(NULL);");
227         $self->pidl("struct $fn->{NAME} r;");
228         $self->pidl("PyObject *result;");
229         my $result_size = 0;
230
231         foreach my $e (@{$fn->{ELEMENTS}}) {
232                 if (grep(/in/,@{$e->{DIRECTION}})) {
233                         $self->pidl("PyObject *py_$e->{NAME};");
234                 }
235                 if (grep(/out/,@{$e->{DIRECTION}})) {
236                         $result_size++;
237                 }
238         }
239         if ($result_size > 0) {
240                 $self->pidl("");
241                 $self->pidl("ZERO_STRUCT(r.out);");
242         }
243         if ($fn->{RETURN_TYPE}) {
244                 $result_size++;
245         }
246
247         foreach my $e (@{$fn->{ELEMENTS}}) {
248                 if (grep(/in/,@{$e->{DIRECTION}})) {
249                         $self->pidl("r.in.$e->{NAME} = " . $self->ConvertObjectFromPython($e->{TYPE}, "py_$e->{NAME}") . ";");
250                 }
251         }
252         $self->pidl("status = dcerpc_$fn->{NAME}(iface->pipe, mem_ctx, &r);");
253         $self->handle_ntstatus("status", "NULL", "mem_ctx");
254
255         $self->pidl("result = PyTuple_New($result_size);");
256
257         my $i = 0;
258
259         foreach my $e (@{$fn->{ELEMENTS}}) {
260                 if (grep(/out/,@{$e->{DIRECTION}})) {
261                         $self->pidl("PyTuple_SetItem(result, $i, " . $self->ConvertObjectToPython($e->{TYPE}, "r.out.$e->{NAME}") . ");");
262
263                         $i++;
264                 }
265         }
266
267         if (defined($fn->{RETURN_TYPE})) {
268                 $self->pidl("PyTuple_SetItem(result, $i, " . $self->ConvertObjectToPython($fn->{RETURN_TYPE}, "r.out.result") . ");");
269         }
270
271         $self->pidl("talloc_free(mem_ctx);");
272         $self->pidl("return result;");
273         $self->deindent;
274         $self->pidl("}");
275         $self->pidl("");
276 }
277
278 sub handle_ntstatus($$$$)
279 {
280         my ($self, $var, $retval, $mem_ctx) = @_;
281
282         $self->pidl("if (NT_STATUS_IS_ERR($var)) {");
283         $self->indent;
284         $self->pidl("PyErr_SetString(PyExc_RuntimeError, nt_errstr($var));");
285         $self->pidl("talloc_free($mem_ctx);") if ($mem_ctx);
286         $self->pidl("return $retval;");
287         $self->deindent;
288         $self->pidl("}");
289         $self->pidl("");
290 }
291
292 sub PythonType($$$)
293 {
294         my ($self, $d, $interface, $basename) = @_;
295
296         my $actual_ctype = $d;
297         if ($actual_ctype->{TYPE} eq "TYPEDEF") {
298                 $actual_ctype = $actual_ctype->{DATA};
299         }
300
301         if ($actual_ctype->{TYPE} eq "STRUCT") {
302                 my $py_fnname;
303                 if ($d->{TYPE} eq "STRUCT") {
304                         $py_fnname = $self->PythonStruct($d->{NAME}, mapTypeName($d), $d);
305                 } else {
306                         $py_fnname = $self->PythonStruct($d->{NAME}, mapTypeName($d), $d->{DATA});
307                 }
308
309                 my $fn_name = $d->{NAME};
310
311                 $fn_name =~ s/^$interface->{NAME}_//;
312                 $fn_name =~ s/^$basename\_//;
313
314                 $self->register_module_method($fn_name, $py_fnname, "METH_VARARGS|METH_KEYWORDS", "NULL");
315         }
316
317         if ($d->{TYPE} eq "ENUM" or $d->{TYPE} eq "BITMAP") {
318                 $self->EnumAndBitmapConsts($d->{NAME}, $d);
319         }
320
321         if ($d->{TYPE} eq "TYPEDEF" and ($d->{DATA}->{TYPE} eq "ENUM" or $d->{DATA}->{TYPE} eq "BITMAP")) {
322                 $self->EnumAndBitmapConsts($d->{NAME}, $d->{DATA});
323         }
324
325         if ($actual_ctype->{TYPE} eq "UNION" or $actual_ctype->{TYPE} eq "STRUCT") {
326                 $self->pidl("PyObject *py_import_$d->{NAME}(" .mapTypeName($d) . " *in)");
327                 $self->pidl("{");
328                 $self->indent;
329                 $self->FromStructToPythonFunction($d, "in") if ($actual_ctype->{TYPE} eq "STRUCT");
330                 $self->FromUnionToPythonFunction($d, "in") if ($actual_ctype->{TYPE} eq "UNION");
331                 $self->deindent;
332                 $self->pidl("}");
333                 $self->pidl("");
334
335                 $self->pidl(mapTypeName($d) . " *py_export_$d->{NAME}(TALLOC_CTX *mem_ctx, PyObject *in)");
336                 $self->pidl("{");
337                 $self->indent;
338                 $self->FromPythonToStructFunction($d, "mem_ctx", "in") if ($actual_ctype->{TYPE} eq "STRUCT");
339                 $self->FromPythonToUnionFunction($d, "mem_ctx", "in") if ($actual_ctype->{TYPE} eq "UNION");
340                 $self->deindent;
341                 $self->pidl("}");
342                 $self->pidl("");
343         }
344 }
345
346 sub Interface($$$)
347 {
348         my($self,$interface,$basename) = @_;
349
350         $self->pidl_hdr("#ifndef _HEADER_PYTHON_$interface->{NAME}\n");
351         $self->pidl_hdr("#define _HEADER_PYTHON_$interface->{NAME}\n\n");
352
353         $self->pidl_hdr("\n");
354
355         $self->Const($_) foreach (@{$interface->{CONSTS}});
356
357         foreach my $d (@{$interface->{TYPES}}) {
358                 next if has_property($d, "nopython");
359
360                 $self->PythonType($d, $interface, $basename);
361         }
362
363         $self->pidl("staticforward PyTypeObject $interface->{NAME}_InterfaceType;");
364         $self->pidl("typedef struct {");
365         $self->indent;
366         $self->pidl("PyObject_HEAD");
367         $self->pidl("struct dcerpc_pipe *pipe;");
368         $self->deindent;
369         $self->pidl("} $interface->{NAME}_InterfaceObject;");
370
371         $self->pidl("");
372
373         foreach my $d (@{$interface->{FUNCTIONS}}) {
374                 next if not defined($d->{OPNUM});
375                 next if has_property($d, "nopython");
376
377                 $self->PythonFunction($d, $interface->{NAME});
378         }
379
380         $self->pidl("static PyMethodDef interface_$interface->{NAME}\_methods[] = {");
381         $self->indent;
382         foreach my $d (@{$interface->{FUNCTIONS}}) {
383                 next if not defined($d->{OPNUM});
384                 next if has_property($d, "nopython");
385
386                 my $fn_name = $d->{NAME};
387
388                 $fn_name =~ s/^$interface->{NAME}_//;
389
390                 $self->pidl("{ \"$fn_name\", (PyCFunction)py_$d->{NAME}, METH_VARARGS|METH_KEYWORDS, NULL },");
391         }
392         $self->pidl("{ NULL, NULL, 0, NULL }");
393         $self->deindent;
394         $self->pidl("};");
395         $self->pidl("");
396
397         $self->pidl("static void interface_$interface->{NAME}_dealloc(PyObject* self)");
398         $self->pidl("{");
399         $self->indent;
400         $self->pidl("$interface->{NAME}_InterfaceObject *interface = ($interface->{NAME}_InterfaceObject *)self;");
401         $self->pidl("talloc_free(interface->pipe);");
402         $self->pidl("PyObject_Del(self);");
403         $self->deindent;
404         $self->pidl("}");
405         $self->pidl("");
406
407         $self->pidl("static PyObject *interface_$interface->{NAME}_getattr(PyTypeObject *obj, char *name)");
408         $self->pidl("{");
409         $self->indent;
410         $self->pidl("return Py_FindMethod(interface_$interface->{NAME}\_methods, (PyObject *)obj, name);");
411         $self->deindent;
412         $self->pidl("}");
413
414         $self->pidl("");
415
416         $self->pidl("static PyTypeObject $interface->{NAME}_InterfaceType = {");
417         $self->indent;
418         $self->pidl("PyObject_HEAD_INIT(NULL) 0,");
419         $self->pidl(".tp_name = \"$interface->{NAME}\",");
420         $self->pidl(".tp_basicsize = sizeof($interface->{NAME}_InterfaceObject),");
421         $self->pidl(".tp_dealloc = (destructor)interface_$interface->{NAME}_dealloc,");
422         $self->pidl(".tp_getattr = (getattrfunc)interface_$interface->{NAME}_getattr,");
423         $self->deindent;
424         $self->pidl("};");
425
426         $self->pidl("");
427
428         $self->register_module_method($interface->{NAME}, "interface_$interface->{NAME}", "METH_VARARGS|METH_KEYWORDS", "NULL");
429         $self->pidl("static PyObject *interface_$interface->{NAME}(PyObject *self, PyObject *args)");
430         $self->pidl("{");
431         $self->indent;
432         $self->pidl("$interface->{NAME}_InterfaceObject *ret;");
433         $self->pidl("const char *binding_string;");
434         $self->pidl("struct cli_credentials *credentials;");
435         $self->pidl("struct loadparm_context *lp_ctx;");
436         $self->pidl("TALLOC_CTX *mem_ctx = NULL;");
437         $self->pidl("NTSTATUS status;");
438         $self->pidl("");
439
440         # FIXME: Arguments: binding string, credentials, loadparm context
441         $self->pidl("ret = PyObject_New($interface->{NAME}_InterfaceObject, &$interface->{NAME}_InterfaceType);");
442         $self->pidl("");
443
444         $self->pidl("status = dcerpc_pipe_connect(NULL, &ret->pipe, binding_string, ");
445         $self->pidl("             &ndr_table_$interface->{NAME}, credentials, NULL, lp_ctx);");
446         $self->handle_ntstatus("status", "NULL", "mem_ctx");
447
448         $self->pidl("return (PyObject *)ret;");
449         $self->deindent;
450         $self->pidl("}");
451         
452         $self->pidl("");
453
454         $self->pidl_hdr("\n");
455         $self->pidl_hdr("#endif /* _HEADER_NDR_$interface->{NAME} */\n");
456 }
457
458 sub register_module_method($$$$$)
459 {
460         my ($self, $fn_name, $pyfn_name, $flags, $doc) = @_;
461
462         push (@{$self->{module_methods}}, [$fn_name, $pyfn_name, $flags, $doc])
463 }
464
465 sub ConvertObjectFromPython($$$)
466 {
467         my ($self, $ctype, $cvar) = @_;
468
469         die("undef type for $cvar") unless(defined($ctype));
470
471         if (ref($ctype) ne "HASH") {
472                 $ctype = getType($ctype);
473         }
474
475         if (ref($ctype) ne "HASH") {
476                 return "FIXME($cvar)";
477         }
478
479         my $actual_ctype = $ctype;
480         if ($ctype->{TYPE} eq "TYPEDEF") {
481                 $actual_ctype = $ctype->{DATA};
482         }
483
484         if ($actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP" or 
485                 $actual_ctype->{TYPE} eq "SCALAR" and (
486                 expandAlias($actual_ctype->{NAME}) =~ /^(uint[0-9]+|hyper|NTTIME|time_t|NTTIME_hyper|NTTIME_1sec|dlong|udlong)$/)) {
487                 return "PyInt_AsLong($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 (
531                         $actual_ctype->{TYPE} eq "STRUCT" or 
532                         $actual_ctype->{TYPE} eq "UNION")) {
533                 return "py_import_$ctype->{NAME}($cvar)";
534         }
535
536         if ($actual_ctype->{TYPE} eq "SCALAR" and 
537                 expandAlias($actual_ctype->{NAME}) eq "DATA_BLOB") {
538                 return "PyString_FromStringAndSize($cvar->data, $cvar->length)";
539         }
540
541         if ($ctype->{TYPE} eq "STRUCT" or $ctype->{TYPE} eq "UNION") {
542                 return "py_import_$ctype->{TYPE}_$ctype->{NAME}($cvar)";
543         }
544
545         if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "NTSTATUS") {
546                 return "PyInt_FromLong($cvar->v)";
547         }
548
549         if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "WERROR") {
550                 return "PyInt_FromLong($cvar->v)";
551         }
552
553         if ($actual_ctype->{TYPE} eq "SCALAR" and 
554                 ($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")) {
555                 return "PyString_FromString($cvar)";
556         }
557
558         if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "string_array") {
559                 return "FIXME($cvar)";
560         }
561
562         if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "ipv4address") {
563                 return "FIXME($cvar)";
564                 }
565
566         if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "pointer") {
567                 return "PyCObject_FromVoidPtr($cvar, talloc_free)";
568         }
569
570
571         die("unknown type ".mapTypeName($ctype) . ": $cvar");
572 }
573
574 sub Parse($$$$$)
575 {
576     my($self,$basename,$ndr,$ndr_hdr,$hdr) = @_;
577     
578     my $py_hdr = $hdr;
579     $py_hdr =~ s/ndr_([^\/]+)$/py_$1/g;
580
581     $self->pidl_hdr("/* header auto-generated by pidl */\n\n");
582         
583     $self->pidl("
584 /* Python wrapper functions auto-generated by pidl */
585 #include \"includes.h\"
586 #include <Python.h>
587 #include \"librpc/rpc/dcerpc.h\"
588 #include \"$hdr\"
589 #include \"$ndr_hdr\"
590 #include \"$py_hdr\"
591
592 ");
593
594         foreach my $x (@$ndr) {
595             ($x->{TYPE} eq "INTERFACE") && $self->Interface($x, $basename);
596                 ($x->{TYPE} eq "IMPORT") && $self->Import(@{$x->{PATHS}});
597         }
598         
599         $self->pidl("static PyMethodDef $basename\_methods[] = {");
600         $self->indent;
601         foreach (@{$self->{module_methods}}) {
602                 my ($fn_name, $pyfn_name, $flags, $doc) = @$_;
603                 $self->pidl("{ \"$fn_name\", (PyCFunction)$pyfn_name, $flags, $doc },");
604         }
605         
606         $self->pidl("{ NULL, NULL, 0, NULL }");
607         $self->deindent;
608         $self->pidl("};");
609
610         $self->pidl("");
611
612         $self->pidl("void init$basename(void)");
613         $self->pidl("{");
614         $self->indent;
615         $self->pidl("PyObject *m;");
616         $self->pidl("m = Py_InitModule(\"$basename\", $basename\_methods);");
617         foreach (keys %{$self->{constants}}) {
618                 # FIXME: Handle non-string constants
619                 $self->pidl("PyModule_AddObject(m, \"$_\", " .  $self->ConvertObjectToPython($self->{constants}->{$_}->[0], $self->{constants}->{$_}->[1]) . ");");
620         }
621         $self->deindent;
622         $self->pidl("}");
623     return ($self->{res_hdr}, $self->{res});
624 }
625
626 1;