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