2 # (C) 2007 Jelmer Vernooij <jelmer@samba.org>
3 # Published under the GNU General Public License
7 use Test
::More tests
=> 31;
8 use FindBin
qw($RealBin);
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);
18 sub print_fn
($) { my $x = shift; $output.=$x; }
20 # Test case 1: Simple unique pointer dereference
23 my $fn = check_null_pointer
({
31 POINTER_TYPE
=> "unique" },
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
47 $fn = check_null_pointer
({
55 POINTER_TYPE
=> "ref" },
61 }, { bla
=> "r->in.bla" }, \
&print_fn
, undef);
63 test_warnings
("", sub { $fn->("r->in.bla"); });
67 # Test case 3: Illegal dereference
70 $fn = check_null_pointer
({
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"); });
90 # Test case 4: Double pointer dereference
93 $fn = check_null_pointer
({
101 POINTER_TYPE
=> "unique" },
104 POINTER_TYPE
=> "unique" },
110 }, { bla
=> "r->in.bla" }, \
&print_fn
, "return;");
113 sub { $fn->("*r->in.bla"); });
115 is
($output, "if (*r->in.bla == NULL) return;");
117 # Test case 5: Unknown variable
120 $fn = check_null_pointer
({
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;");
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 });
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
167 NeededType
({ NAME
=> "bla", TYPE
=> "TYPEDEF",
168 DATA
=> { TYPE
=> "STRUCT", ELEMENTS
=> [] } },
170 is_deeply
($needed, { });
173 NeededInterface
({ TYPES
=> [ { PROPERTIES
=> { public
=> 1 }, NAME
=> "bla",
175 DATA
=> { TYPE
=> "STRUCT", ELEMENTS
=> [] } } ] },
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
181 NeededInterface
({ TYPES
=> [ { PROPERTIES
=> { public
=> 1 }, NAME
=> "bla",
183 DATA
=> { TYPE
=> "STRUCT",
184 ELEMENTS
=> [ { TYPE
=> "bar", REPRESENTATION_TYPE
=> "bar" } ] } } ] },
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});
190 NeededInterface
({ TYPES
=> [ { PROPERTIES
=> { gensize
=> 1}, NAME
=> "bla",
192 DATA
=> { TYPE
=> "STRUCT",
193 ELEMENTS
=> [ { TYPE
=> "bar", REPRESENTATION_TYPE
=> "bar" } ] } } ] },
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",
201 DATA
=> { TYPE
=> "STRUCT",
202 ELEMENTS
=> [ { TYPE
=> "bar", REPRESENTATION_TYPE
=> "bar" } ] } },
204 is_deeply
($needed, { ndr_pull_bla
=> 1, ndr_pull_bar
=> 1 });
207 NeededInterface
({ TYPES
=> [ { PROPERTIES
=> { public
=> 1},
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,
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({
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
();
236 REPRESENTATION_TYPE
=> "mytype",
239 { LEVEL_INDEX
=> 0, TYPE
=> "DATA", DATA_TYPE
=> "mytype" }
241 $generator->ParseStructPush({
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",
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[] = {
293 static const struct ndr_interface_string_array bridge_authservices = {
295 .names = bridge_authservice_strings