s3-docs: fix a typo in rpcclient manpage
[Samba/bb.git] / pidl / tests / samba-ndr.pl
blobe2578178099f21ca73ba73705e9d5b6707508ff2
1 #!/usr/bin/perl
2 # (C) 2007 Jelmer Vernooij <jelmer@samba.org>
3 # Published under the GNU General Public License
4 use strict;
5 use warnings;
7 use Test::More tests => 31;
8 use FindBin qw($RealBin);
9 use lib "$RealBin";
10 use Util;
11 use strict;
12 use Parse::Pidl::Util qw(MyDumper);
13 use Parse::Pidl::Samba4::NDR::Parser qw(check_null_pointer
14 NeededFunction NeededElement NeededType
15 NeededInterface TypeFunctionName ParseElementPrint);
17 my $output;
18 sub print_fn($) { my $x = shift; $output.=$x; }
20 # Test case 1: Simple unique pointer dereference
22 $output = "";
23 my $fn = check_null_pointer({
24 PARENT => {
25 ELEMENTS => [
27 NAME => "bla",
28 LEVELS => [
29 { TYPE => "POINTER",
30 POINTER_INDEX => 0,
31 POINTER_TYPE => "unique" },
32 { TYPE => "DATA" }
37 }, { bla => "r->in.bla" }, \&print_fn, "return;");
40 test_warnings("", sub { $fn->("r->in.bla"); });
42 is($output, "if (r->in.bla == NULL) return;");
44 # Test case 2: Simple ref pointer dereference
46 $output = "";
47 $fn = check_null_pointer({
48 PARENT => {
49 ELEMENTS => [
51 NAME => "bla",
52 LEVELS => [
53 { TYPE => "POINTER",
54 POINTER_INDEX => 0,
55 POINTER_TYPE => "ref" },
56 { TYPE => "DATA" }
61 }, { bla => "r->in.bla" }, \&print_fn, undef);
63 test_warnings("", sub { $fn->("r->in.bla"); });
65 is($output, "");
67 # Test case 3: Illegal dereference
69 $output = "";
70 $fn = check_null_pointer({
71 FILE => "nofile",
72 LINE => 1,
73 PARENT => {
74 ELEMENTS => [
76 NAME => "bla",
77 LEVELS => [
78 { TYPE => "DATA" }
83 }, { bla => "r->in.bla" }, \&print_fn, undef);
85 test_warnings("nofile:1: too much dereferences for `bla'\n",
86 sub { $fn->("r->in.bla"); });
88 is($output, "");
90 # Test case 4: Double pointer dereference
92 $output = "";
93 $fn = check_null_pointer({
94 PARENT => {
95 ELEMENTS => [
97 NAME => "bla",
98 LEVELS => [
99 { TYPE => "POINTER",
100 POINTER_INDEX => 0,
101 POINTER_TYPE => "unique" },
102 { TYPE => "POINTER",
103 POINTER_INDEX => 1,
104 POINTER_TYPE => "unique" },
105 { TYPE => "DATA" }
110 }, { bla => "r->in.bla" }, \&print_fn, "return;");
112 test_warnings("",
113 sub { $fn->("*r->in.bla"); });
115 is($output, "if (*r->in.bla == NULL) return;");
117 # Test case 5: Unknown variable
119 $output = "";
120 $fn = check_null_pointer({
121 FILE => "nofile",
122 LINE => 2,
123 PARENT => {
124 ELEMENTS => [
126 NAME => "bla",
127 LEVELS => [
128 { TYPE => "DATA" }
133 }, { }, \&print_fn, "return;");
135 test_warnings("nofile:2: unknown dereferenced expression `r->in.bla'\n",
136 sub { $fn->("r->in.bla"); });
138 is($output, "if (r->in.bla == NULL) return;");
140 my $needed = {};
141 NeededElement({ TYPE => "foo", REPRESENTATION_TYPE => "foo" }, "pull", $needed);
142 is_deeply($needed, { ndr_pull_foo => 1 });
144 # old settings should be kept
145 $needed = { ndr_pull_foo => 0 };
146 NeededElement({ TYPE => "foo", REPRESENTATION_TYPE => "foo" }, "pull", $needed);
147 is_deeply($needed, { ndr_pull_foo => 0 });
149 # print/pull/push are independent of each other
150 $needed = { ndr_pull_foo => 0 };
151 NeededElement({ TYPE => "foo", REPRESENTATION_TYPE => "foo" }, "print", $needed);
152 is_deeply($needed, { ndr_pull_foo => 0, ndr_print_foo => 1 });
154 $needed = { };
155 NeededFunction({ NAME => "foo", ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "bar" } ] }, $needed);
156 is_deeply($needed, { ndr_pull_foo => 1, ndr_print_foo => 1, ndr_push_foo => 1,
157 ndr_pull_bar => 1, ndr_print_bar => 1, ndr_push_bar => 1});
159 # push/pull/print are always set for functions
160 $needed = { ndr_pull_foo => 0 };
161 NeededFunction({ NAME => "foo", ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "bar" } ] }, $needed);
162 is_deeply($needed, { ndr_pull_foo => 1, ndr_print_foo => 1, ndr_push_foo => 1,
163 ndr_pull_bar => 1, ndr_push_bar => 1, ndr_print_bar => 1});
165 # public structs are always needed
166 $needed = {};
167 NeededType({ NAME => "bla", TYPE => "TYPEDEF",
168 DATA => { TYPE => "STRUCT", ELEMENTS => [] } },
169 $needed, "pull");
170 is_deeply($needed, { });
172 $needed = {};
173 NeededInterface({ TYPES => [ { PROPERTIES => { public => 1 }, NAME => "bla",
174 TYPE => "TYPEDEF",
175 DATA => { TYPE => "STRUCT", ELEMENTS => [] } } ] },
176 $needed);
177 is_deeply($needed, { ndr_pull_bla => 1, ndr_push_bla => 1, ndr_print_bla => 1 });
179 # make sure types for elements are set too
180 $needed = {};
181 NeededInterface({ TYPES => [ { PROPERTIES => { public => 1 }, NAME => "bla",
182 TYPE => "TYPEDEF",
183 DATA => { TYPE => "STRUCT",
184 ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "bar" } ] } } ] },
185 $needed);
186 is_deeply($needed, { ndr_pull_bla => 1, ndr_pull_bar => 1, ndr_push_bla => 1, ndr_push_bar => 1,
187 ndr_print_bla => 1, ndr_print_bar => 1});
189 $needed = {};
190 NeededInterface({ TYPES => [ { PROPERTIES => { gensize => 1}, NAME => "bla",
191 TYPE => "TYPEDEF",
192 DATA => { TYPE => "STRUCT",
193 ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "bar" } ] } } ] },
194 $needed);
195 is_deeply($needed, { ndr_size_bla => 1 });
197 # make sure types for elements are set too
198 $needed = { ndr_pull_bla => 1 };
199 NeededType({ NAME => "bla",
200 TYPE => "TYPEDEF",
201 DATA => { TYPE => "STRUCT",
202 ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "bar" } ] } },
203 $needed, "pull");
204 is_deeply($needed, { ndr_pull_bla => 1, ndr_pull_bar => 1 });
206 $needed = {};
207 NeededInterface({ TYPES => [ { PROPERTIES => { public => 1},
208 NAME => "bla",
209 TYPE => "TYPEDEF",
210 DATA => { TYPE => "STRUCT",
211 ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "rep" } ] } } ] }, $needed);
212 is_deeply($needed, { ndr_pull_bla => 1, ndr_push_bla => 1, ndr_print_bla => 1,
213 ndr_print_rep => 1,
214 ndr_pull_bar => 1, ndr_push_bar => 1,
215 ndr_bar_to_rep => 1, ndr_rep_to_bar => 1});
217 my $generator = new Parse::Pidl::Samba4::NDR::Parser();
218 $generator->ParseStructPush({
219 NAME => "mystruct",
220 TYPE => "STRUCT",
221 PROPERTIES => {},
222 ALIGN => 4,
223 ELEMENTS => [ ]}, "ndr", "x");
224 is($generator->{res}, "if (ndr_flags & NDR_SCALARS) {
225 NDR_CHECK(ndr_push_align(ndr, 4));
226 NDR_CHECK(ndr_push_trailer_align(ndr, 4));
228 if (ndr_flags & NDR_BUFFERS) {
232 $generator = new Parse::Pidl::Samba4::NDR::Parser();
233 my $e = {
234 NAME => "el1",
235 TYPE => "mytype",
236 REPRESENTATION_TYPE => "mytype",
237 PROPERTIES => {},
238 LEVELS => [
239 { LEVEL_INDEX => 0, TYPE => "DATA", DATA_TYPE => "mytype" }
240 ] };
241 $generator->ParseStructPush({
242 NAME => "mystruct",
243 TYPE => "STRUCT",
244 PROPERTIES => {},
245 ALIGN => 4,
246 SURROUNDING_ELEMENT => $e,
247 ELEMENTS => [ $e ]}, "ndr", "x");
248 is($generator->{res}, "if (ndr_flags & NDR_SCALARS) {
249 NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, ndr_string_array_size(ndr, x->el1)));
250 NDR_CHECK(ndr_push_align(ndr, 4));
251 NDR_CHECK(ndr_push_mytype(ndr, NDR_SCALARS, &x->el1));
252 NDR_CHECK(ndr_push_trailer_align(ndr, 4));
254 if (ndr_flags & NDR_BUFFERS) {
258 is(TypeFunctionName("ndr_pull", "uint32"), "ndr_pull_uint32");
259 is(TypeFunctionName("ndr_pull", {TYPE => "ENUM", NAME => "bar"}), "ndr_pull_ENUM_bar");
260 is(TypeFunctionName("ndr_pull", {TYPE => "TYPEDEF", NAME => "bar", DATA => undef}), "ndr_pull_bar");
261 is(TypeFunctionName("ndr_push", {TYPE => "STRUCT", NAME => "bar"}), "ndr_push_STRUCT_bar");
263 # check noprint works
264 $generator = new Parse::Pidl::Samba4::NDR::Parser();
265 $generator->ParseElementPrint({ NAME => "x", TYPE => "rt", REPRESENTATION_TYPE => "rt",
266 PROPERTIES => { noprint => 1},
267 LEVELS => [ { TYPE => "DATA", DATA_TYPE => "rt"} ]},
268 "ndr", "var", { "x" => "r->foobar" } );
269 is($generator->{res}, "");
271 $generator = new Parse::Pidl::Samba4::NDR::Parser();
272 $generator->ParseElementPrint({ NAME => "x", TYPE => "rt", REPRESENTATION_TYPE => "rt",
273 PROPERTIES => {},
274 LEVELS => [ { TYPE => "DATA", DATA_TYPE => "rt" }]},
275 "ndr", "var", { "x" => "r->foobar" } );
276 is($generator->{res}, "ndr_print_rt(ndr, \"x\", &var);\n");
278 # make sure that a print function for an element with value() set works
279 $generator = new Parse::Pidl::Samba4::NDR::Parser();
280 $generator->ParseElementPrint({ NAME => "x", TYPE => "uint32", REPRESENTATION_TYPE => "uint32",
281 PROPERTIES => { value => "23" },
282 LEVELS => [ { TYPE => "DATA", DATA_TYPE => "uint32"} ]},
283 "ndr", "var", { "x" => "r->foobar" } );
284 is($generator->{res}, "ndr_print_uint32(ndr, \"x\", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?23:var);\n");
286 $generator = new Parse::Pidl::Samba4::NDR::Parser();
287 $generator->AuthServiceStruct("bridge", "\"rot13\",\"onetimepad\"");
288 is($generator->{res}, "static const char * const bridge_authservice_strings[] = {
289 \"rot13\",
290 \"onetimepad\",
293 static const struct ndr_interface_string_array bridge_authservices = {
294 .count = 2,
295 .names = bridge_authservice_strings