pidl:NDR/Client.pm: generate explicit _recv functions
[ira/wip.git] / pidl / lib / Parse / Pidl / Samba4 / NDR / Client.pm
1 ###################################################
2 # client calls generator
3 # Copyright tridge@samba.org 2003
4 # Copyright jelmer@samba.org 2005-2006
5 # released under the GNU GPL
6
7 package Parse::Pidl::Samba4::NDR::Client;
8
9 use Parse::Pidl::Samba4 qw(choose_header is_intree);
10 use Parse::Pidl::Util qw(has_property);
11
12 use vars qw($VERSION);
13 $VERSION = '0.01';
14
15 use strict;
16
17 my($res,$res_hdr);
18
19 sub ParseFunctionSend($$$)
20 {
21         my ($interface, $fn, $name) = @_;
22         my $uname = uc $name;
23
24         my $proto = "struct rpc_request *dcerpc_$name\_send(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r)";
25
26         $res_hdr .= "\n$proto;\n";
27
28         $res .= "$proto\n{\n";
29
30         if (has_property($fn, "todo")) {
31                 $res .= "\treturn NULL;\n";
32         } else {
33                 $res .= "
34         if (p->conn->flags & DCERPC_DEBUG_PRINT_IN) {
35                 NDR_PRINT_IN_DEBUG($name, r);
36         }
37
38         return dcerpc_ndr_request_send(p, NULL, &ndr_table_$interface->{NAME},
39                                        NDR_$uname, true, mem_ctx, r);
40 ";
41         }
42
43         $res .= "}\n\n";
44 }
45
46 sub ParseFunctionRecv($$$)
47 {
48         my ($interface, $fn, $name) = @_;
49         my $uname = uc $name;
50
51         my $proto = "NTSTATUS dcerpc_$name\_recv(struct rpc_request *rreq)";
52
53         $res_hdr .= "\n$proto;\n";
54
55         $res .= "$proto\n{\n";
56
57         if (has_property($fn, "todo")) {
58                 $res .= "\treturn NT_STATUS_NOT_IMPLEMENTED;\n";
59         } else {
60                 $res .= "NTSTATUS status;
61         struct dcerpc_pipe *p = rreq->p;
62         struct $name *r = (struct $name *)rreq->ndr.struct_ptr;
63
64         status = dcerpc_ndr_request_recv(rreq);
65
66         if (NT_STATUS_IS_OK(status) && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
67                 NDR_PRINT_OUT_DEBUG($name, r);
68         }
69
70         return status;
71 ";
72         }
73
74         $res .= "}\n\n";
75 }
76
77 sub ParseFunctionSync($$$)
78 {
79         my ($interface, $fn, $name) = @_;
80         my $uname = uc $name;
81
82         my $proto = "NTSTATUS dcerpc_$name(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r)";
83
84         $res_hdr .= "\n$proto;\n";
85         $res .= "$proto\n{\n";
86
87         if (has_property($fn, "todo")) {
88                 $res .= "\treturn NT_STATUS_NOT_IMPLEMENTED;\n";
89         } else {
90                 $res .= "
91         NTSTATUS status;
92
93         if (p->conn->flags & DCERPC_DEBUG_PRINT_IN) {
94                 NDR_PRINT_IN_DEBUG($name, r);
95         }
96
97         status = dcerpc_ndr_request(p, NULL, &ndr_table_$interface->{NAME},
98                                     NDR_$uname, mem_ctx, r);
99
100         if (NT_STATUS_IS_OK(status) && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
101                 NDR_PRINT_OUT_DEBUG($name, r);          
102         }
103 ";
104     
105         if (defined($fn->{RETURN_TYPE}) and $fn->{RETURN_TYPE} eq "NTSTATUS") {
106              $res .= "\tif (NT_STATUS_IS_OK(status)) status = r->out.result;\n";
107         }
108         $res .= 
109 "
110         return status;
111 ";
112         }
113
114         $res .= "}\n\n";
115 }
116
117 #####################################################################
118 # parse a function
119 sub ParseFunction($$)
120 {
121         my ($interface, $fn) = @_;
122
123         ParseFunctionSend($interface, $fn, $fn->{NAME});
124         ParseFunctionRecv($interface, $fn, $fn->{NAME});
125         ParseFunctionSync($interface, $fn, $fn->{NAME});
126 }
127
128 my %done;
129
130 #####################################################################
131 # parse the interface definitions
132 sub ParseInterface($)
133 {
134         my($interface) = shift;
135
136         $res_hdr .= "#ifndef _HEADER_RPC_$interface->{NAME}\n";
137         $res_hdr .= "#define _HEADER_RPC_$interface->{NAME}\n\n";
138
139         if (defined $interface->{PROPERTIES}->{uuid}) {
140                 $res_hdr .= "extern const struct ndr_interface_table ndr_table_$interface->{NAME};\n";
141         }
142
143         $res .= "/* $interface->{NAME} - client functions generated by pidl */\n\n";
144
145         foreach my $fn (@{$interface->{FUNCTIONS}}) {
146                 next if not defined($fn->{OPNUM});
147                 next if defined($done{$fn->{NAME}});
148                 ParseFunction($interface, $fn);
149                 $done{$fn->{NAME}} = 1;
150         }
151
152         $res_hdr .= "#endif /* _HEADER_RPC_$interface->{NAME} */\n";
153
154         return $res;
155 }
156
157 sub Parse($$$$)
158 {
159         my($ndr,$header,$ndr_header,$client_header) = @_;
160
161         $res = "";
162         $res_hdr = "";
163
164         $res .= "/* client functions auto-generated by pidl */\n";
165         $res .= "\n";
166         if (is_intree()) {
167                 $res .= "#include \"includes.h\"\n";
168         } else {
169                 $res .= "#ifndef _GNU_SOURCE\n";
170                 $res .= "#define _GNU_SOURCE\n";
171                 $res .= "#endif\n";
172                 $res .= "#include <stdio.h>\n";
173                 $res .= "#include <stdbool.h>\n";
174                 $res .= "#include <stdlib.h>\n";
175                 $res .= "#include <stdint.h>\n";
176                 $res .= "#include <stdarg.h>\n";
177                 $res .= "#include <core/ntstatus.h>\n";
178         }
179         $res .= "#include \"$ndr_header\"\n";
180         $res .= "#include \"$client_header\"\n";
181         $res .= "\n";
182
183         $res_hdr .= choose_header("librpc/rpc/dcerpc.h", "dcerpc.h")."\n";
184         $res_hdr .= "#include \"$header\"\n";
185
186         foreach my $x (@{$ndr}) {
187                 ($x->{TYPE} eq "INTERFACE") && ParseInterface($x);
188         }
189
190         return ($res,$res_hdr);
191 }
192
193 1;