r21384: Change warning to pidl warning, fix uppercasing.
[Samba/ekacnet.git] / source / pidl / lib / Parse / Pidl / Samba3 / ClientNDR.pm
blob0ffa321782f9f4b0323f6e26b12a2b71d80fd055
1 ###################################################
2 # Samba3 client generator for IDL structures
3 # on top of Samba4 style NDR functions
4 # Copyright jelmer@samba.org 2005-2006
5 # released under the GNU GPL
7 package Parse::Pidl::Samba3::ClientNDR;
9 use Exporter;
10 @ISA = qw(Exporter);
11 @EXPORT_OK = qw(GenerateFunctionInEnv ParseFunction $res $res_hdr);
13 use strict;
14 use Parse::Pidl qw(fatal warning);
15 use Parse::Pidl::Typelist qw(hasType getType mapType scalar_is_reference);
16 use Parse::Pidl::Util qw(has_property is_constant ParseExpr);
17 use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred);
18 use Parse::Pidl::Samba4 qw(DeclLong);
20 use vars qw($VERSION);
21 $VERSION = '0.01';
23 our $res;
24 our $res_hdr;
25 my $tabs = "";
26 sub indent() { $tabs.="\t"; }
27 sub deindent() { $tabs = substr($tabs, 1); }
28 sub pidl($) { $res .= $tabs.(shift)."\n"; }
29 sub pidl_hdr($) { $res_hdr .= (shift)."\n"; }
30 sub fn_declare($) { my ($n) = @_; pidl $n; pidl_hdr "$n;"; }
32 sub GenerateFunctionInEnv($)
34 my $fn = shift;
35 my %env;
37 foreach my $e (@{$fn->{ELEMENTS}}) {
38 if (grep (/in/, @{$e->{DIRECTION}})) {
39 $env{$e->{NAME}} = "r.in.$e->{NAME}";
43 return \%env;
46 sub ParseFunction($$)
48 my ($uif, $fn) = @_;
50 my $inargs = "";
51 my $defargs = "";
52 my $ufn = "DCERPC_".uc($fn->{NAME});
54 foreach (@{$fn->{ELEMENTS}}) {
55 $defargs .= ", " . DeclLong($_);
57 fn_declare "NTSTATUS rpccli_$fn->{NAME}(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx$defargs)";
58 pidl "{";
59 indent;
60 pidl "struct $fn->{NAME} r;";
61 pidl "NTSTATUS status;";
62 pidl "";
63 pidl "/* In parameters */";
65 foreach (@{$fn->{ELEMENTS}}) {
66 if (grep(/in/, @{$_->{DIRECTION}})) {
67 pidl "r.in.$_->{NAME} = $_->{NAME};";
71 pidl "";
72 pidl "if (DEBUGLEVEL >= 10)";
73 pidl "\tNDR_PRINT_IN_DEBUG($fn->{NAME}, &r);";
74 pidl "";
75 pidl "status = cli_do_rpc_ndr(cli, mem_ctx, PI_$uif, $ufn, &r, (ndr_pull_flags_fn_t)ndr_pull_$fn->{NAME}, (ndr_push_flags_fn_t)ndr_push_$fn->{NAME});";
76 pidl "";
78 pidl "if (!NT_STATUS_IS_OK(status)) {";
79 indent;
80 pidl "return status;";
81 deindent;
82 pidl "}";
84 pidl "";
85 pidl "if (DEBUGLEVEL >= 10)";
86 pidl "\tNDR_PRINT_OUT_DEBUG($fn->{NAME}, &r);";
87 pidl "";
88 pidl "if (NT_STATUS_IS_ERR(status)) {";
89 pidl "\treturn status;";
90 pidl "}";
91 pidl "";
92 pidl "/* Return variables */";
93 foreach my $e (@{$fn->{ELEMENTS}}) {
94 next unless (grep(/out/, @{$e->{DIRECTION}}));
96 fatal($e, "[out] argument is not a pointer or array") if ($e->{LEVELS}[0]->{TYPE} ne "POINTER" and $e->{LEVELS}[0]->{TYPE} ne "ARRAY");
98 if ( ($e->{LEVELS}[0]->{TYPE} eq "POINTER") and
99 ($e->{LEVELS}[0]->{POINTER_TYPE} ne "ref") ) {
100 pidl "if ( $e->{NAME} ) {";
101 indent;
104 if ($e->{LEVELS}[0]->{TYPE} eq "ARRAY") {
105 # This is a call to GenerateFunctionInEnv intentionally.
106 # Since the data is being copied into a user-provided data
107 # structure, the user should be able to know the size beforehand
108 # to allocate a structure of the right size.
109 my $env = GenerateFunctionInEnv($fn);
110 my $size_is = ParseExpr($e->{LEVELS}[0]->{SIZE_IS}, $env, $e);
111 pidl "memcpy($e->{NAME}, r.out.$e->{NAME}, $size_is);";
112 } else {
113 pidl "*$e->{NAME} = *r.out.$e->{NAME};";
116 if ( ($e->{LEVELS}[0]->{TYPE} eq "POINTER") and
117 ($e->{LEVELS}[0]->{POINTER_TYPE} ne "ref") ) {
118 deindent;
119 pidl "}";
123 pidl"";
124 pidl "/* Return result */";
125 if (not $fn->{RETURN_TYPE}) {
126 pidl "return NT_STATUS_OK;";
127 } elsif ($fn->{RETURN_TYPE} eq "NTSTATUS") {
128 pidl "return r.out.result;";
129 } elsif ($fn->{RETURN_TYPE} eq "WERROR") {
130 pidl "return werror_to_ntstatus(r.out.result);";
131 } else {
132 warning($fn->{ORIGINAL}, "Unable to convert $fn->{RETURN_TYPE} to NTSTATUS");
133 pidl "return NT_STATUS_OK;";
136 deindent;
137 pidl "}";
138 pidl "";
141 sub ParseInterface($)
143 my $if = shift;
145 my $uif = uc($if->{NAME});
147 pidl_hdr "#ifndef __CLI_$uif\__";
148 pidl_hdr "#define __CLI_$uif\__";
149 ParseFunction(uc($if->{NAME}), $_) foreach (@{$if->{FUNCTIONS}});
150 pidl_hdr "#endif /* __CLI_$uif\__ */";
153 sub Parse($$$)
155 my($ndr,$header,$ndr_header) = @_;
157 $res = "";
158 $res_hdr = "";
160 pidl "/*";
161 pidl " * Unix SMB/CIFS implementation.";
162 pidl " * client auto-generated by pidl. DO NOT MODIFY!";
163 pidl " */";
164 pidl "";
165 pidl "#include \"includes.h\"";
166 pidl "#include \"$header\"";
167 pidl_hdr "#include \"$ndr_header\"";
168 pidl "";
170 foreach (@$ndr) {
171 ParseInterface($_) if ($_->{TYPE} eq "INTERFACE");
174 return ($res, $res_hdr);