r26659: pidl/python: Support string constants and handle modules.
[ira/wip.git] / source / pidl / lib / Parse / Pidl / Samba4 / Python.pm
1 ###################################################
2 # Python function wrapper generator
3 # Copyright jelmer@samba.org 2007
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;
13 use Parse::Pidl::Util qw(has_property ParseExpr);
14
15 use vars qw($VERSION);
16 $VERSION = '0.01';
17
18 sub new($) {
19         my ($class) = @_;
20         my $self = { res => "", res_hdr => "", tabs => "", constants => {}};
21         bless($self, $class);
22 }
23
24 sub pidl_hdr ($$)
25 {
26         my $self = shift;
27         $self->{res_hdr} .= shift;
28 }
29
30 sub pidl($$)
31 {
32         my ($self, $d) = @_;
33         if ($d) {
34                 $self->{res} .= $self->{tabs};
35                 $self->{res} .= $d;
36         }
37         $self->{res} .= "\n";
38 }
39
40 sub indent($)
41 {
42         my ($self) = @_;
43         $self->{tabs} .= "\t";
44 }
45
46 sub deindent($)
47 {
48         my ($self) = @_;
49         $self->{tabs} = substr($self->{tabs}, 0, -1);
50 }
51
52 sub Import
53 {
54         my $self = shift;
55         my @imports = @_;
56         foreach (@imports) {
57                 s/\.idl\"$//;
58                 s/^\"//;
59                 $self->pidl_hdr("#include \"librpc/gen_ndr/py_$_\.h\"\n");
60         }
61 }
62
63 sub Const($$)
64 {
65     my ($self, $const) = @_;
66     $self->{constants}->{$const->{NAME}} = [$const->{DATA}->{TYPE}, $const->{VALUE}];
67 }
68
69 sub Interface($$)
70 {
71         my($self,$interface) = @_;
72
73         $self->pidl_hdr("#ifndef _HEADER_PYTHON_$interface->{NAME}\n");
74         $self->pidl_hdr("#define _HEADER_PYTHON_$interface->{NAME}\n\n");
75
76         $self->pidl_hdr("\n");
77
78         $self->Const($_) foreach (@{$interface->{CONSTS}});
79
80         $self->pidl_hdr("\n");
81         $self->pidl_hdr("#endif /* _HEADER_NDR_$interface->{NAME} */\n");
82 }
83
84 sub Parse($$$$)
85 {
86     my($self,$basename,$ndr,$hdr) = @_;
87     
88     my $py_hdr = $hdr;
89     $py_hdr =~ s/ndr_([^\/]+)$/py_$1/g;
90
91     $self->pidl_hdr("/* header auto-generated by pidl */\n\n");
92         
93     $self->pidl("
94 /* Python wrapper functions auto-generated by pidl */
95 #include \"includes.h\"
96 #include <Python.h>
97 #include \"$hdr\"
98 #include \"$py_hdr\"
99
100 ");
101
102         foreach my $x (@$ndr) {
103             ($x->{TYPE} eq "INTERFACE") && $self->Interface($x);
104                 ($x->{TYPE} eq "IMPORT") && $self->Import(@{$x->{PATHS}});
105         }
106         
107         $self->pidl("static PyMethodDef $basename\_methods[] = {");
108         $self->indent;
109         $self->pidl("{ NULL, NULL, 0, NULL }");
110         $self->deindent;
111         $self->pidl("};");
112
113         $self->pidl("");
114
115         $self->pidl("void init$basename(void)");
116         $self->pidl("{");
117         $self->indent;
118         $self->pidl("PyObject *m, *d;");
119         $self->pidl("m = Py_InitModule((char *)\"$basename\", $basename\_methods);");
120         $self->pidl("d = PyModule_GetDict(m);");
121         foreach (keys %{$self->{constants}}) {
122                 # FIXME: Handle non-string constants
123                 $self->pidl("PyDict_SetItemString(d, \"$_\", PyString_FromString(" . $self->{constants}->{$_}->[1] . "));");
124         }
125         $self->deindent;
126         $self->pidl("}");
127     return ($self->{res_hdr}, $self->{res});
128 }
129
130 1;