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);
11 use Parse::Pidl::Util qw(MyDumper);
12 use Parse
::Pidl
::Samba4
::NDR
::Parser
qw(check_null_pointer
13 NeededFunction NeededElement NeededType
14 NeededInterface TypeFunctionName ParseElementPrint);
17 sub print_fn
($) { my $x = shift; $output.=$x; }
19 # Test case 1: Simple unique pointer dereference
22 my $fn = check_null_pointer
({
30 POINTER_TYPE
=> "unique" },
36 }, { bla
=> "r->in.bla" }, \
&print_fn
, "return;");
39 test_warnings
("", sub { $fn->("r->in.bla"); });
41 is
($output, "if (r->in.bla == NULL) return;");
43 # Test case 2: Simple ref pointer dereference
46 $fn = check_null_pointer
({
54 POINTER_TYPE
=> "ref" },
60 }, { bla
=> "r->in.bla" }, \
&print_fn
, undef);
62 test_warnings
("", sub { $fn->("r->in.bla"); });
66 # Test case 3: Illegal dereference
69 $fn = check_null_pointer
({
82 }, { bla
=> "r->in.bla" }, \
&print_fn
, undef);
84 test_warnings
("nofile:1: too much dereferences for `bla'\n",
85 sub { $fn->("r->in.bla"); });
89 # Test case 4: Double pointer dereference
92 $fn = check_null_pointer
({
100 POINTER_TYPE
=> "unique" },
103 POINTER_TYPE
=> "unique" },
109 }, { bla
=> "r->in.bla" }, \
&print_fn
, "return;");
112 sub { $fn->("*r->in.bla"); });
114 is
($output, "if (*r->in.bla == NULL) return;");
116 # Test case 5: Unknown variable
119 $fn = check_null_pointer
({
132 }, { }, \
&print_fn
, "return;");
134 test_warnings
("nofile:2: unknown dereferenced expression `r->in.bla'\n",
135 sub { $fn->("r->in.bla"); });
137 is
($output, "if (r->in.bla == NULL) return;");
140 NeededElement
({ TYPE
=> "foo", REPRESENTATION_TYPE
=> "foo" }, "pull", $needed);
141 is_deeply
($needed, { ndr_pull_foo
=> 1 });
143 # old settings should be kept
144 $needed = { ndr_pull_foo
=> 0 };
145 NeededElement
({ TYPE
=> "foo", REPRESENTATION_TYPE
=> "foo" }, "pull", $needed);
146 is_deeply
($needed, { ndr_pull_foo
=> 0 });
148 # print/pull/push are independent of each other
149 $needed = { ndr_pull_foo
=> 0 };
150 NeededElement
({ TYPE
=> "foo", REPRESENTATION_TYPE
=> "foo" }, "print", $needed);
151 is_deeply
($needed, { ndr_pull_foo
=> 0, ndr_print_foo
=> 1 });
154 NeededFunction
({ NAME
=> "foo", ELEMENTS
=> [ { TYPE
=> "bar", REPRESENTATION_TYPE
=> "bar" } ] }, $needed);
155 is_deeply
($needed, { ndr_pull_foo
=> 1, ndr_print_foo
=> 1, ndr_push_foo
=> 1,
156 ndr_pull_bar
=> 1, ndr_print_bar
=> 1, ndr_push_bar
=> 1});
158 # push/pull/print are always set for functions
159 $needed = { ndr_pull_foo
=> 0 };
160 NeededFunction
({ NAME
=> "foo", ELEMENTS
=> [ { TYPE
=> "bar", REPRESENTATION_TYPE
=> "bar" } ] }, $needed);
161 is_deeply
($needed, { ndr_pull_foo
=> 1, ndr_print_foo
=> 1, ndr_push_foo
=> 1,
162 ndr_pull_bar
=> 1, ndr_push_bar
=> 1, ndr_print_bar
=> 1});
164 # public structs are always needed
166 NeededType
({ NAME
=> "bla", TYPE
=> "TYPEDEF",
167 DATA
=> { TYPE
=> "STRUCT", ELEMENTS
=> [] } },
169 is_deeply
($needed, { });
172 NeededInterface
({ TYPES
=> [ { PROPERTIES
=> { public
=> 1 }, NAME
=> "bla",
174 DATA
=> { TYPE
=> "STRUCT", ELEMENTS
=> [] } } ] },
176 is_deeply
($needed, { ndr_pull_bla
=> 1, ndr_push_bla
=> 1, ndr_print_bla
=> 1 });
178 # make sure types for elements are set too
180 NeededInterface
({ TYPES
=> [ { PROPERTIES
=> { public
=> 1 }, NAME
=> "bla",
182 DATA
=> { TYPE
=> "STRUCT",
183 ELEMENTS
=> [ { TYPE
=> "bar", REPRESENTATION_TYPE
=> "bar" } ] } } ] },
185 is_deeply
($needed, { ndr_pull_bla
=> 1, ndr_pull_bar
=> 1, ndr_push_bla
=> 1, ndr_push_bar
=> 1,
186 ndr_print_bla
=> 1, ndr_print_bar
=> 1});
189 NeededInterface
({ TYPES
=> [ { PROPERTIES
=> { gensize
=> 1}, NAME
=> "bla",
191 DATA
=> { TYPE
=> "STRUCT",
192 ELEMENTS
=> [ { TYPE
=> "bar", REPRESENTATION_TYPE
=> "bar" } ] } } ] },
194 is_deeply
($needed, { ndr_size_bla
=> 1 });
196 # make sure types for elements are set too
197 $needed = { ndr_pull_bla
=> 1 };
198 NeededType
({ NAME
=> "bla",
200 DATA
=> { TYPE
=> "STRUCT",
201 ELEMENTS
=> [ { TYPE
=> "bar", REPRESENTATION_TYPE
=> "bar" } ] } },
203 is_deeply
($needed, { ndr_pull_bla
=> 1, ndr_pull_bar
=> 1 });
206 NeededInterface
({ TYPES
=> [ { PROPERTIES
=> { public
=> 1},
209 DATA
=> { TYPE
=> "STRUCT",
210 ELEMENTS
=> [ { TYPE
=> "bar", REPRESENTATION_TYPE
=> "rep" } ] } } ] }, $needed);
211 is_deeply
($needed, { ndr_pull_bla
=> 1, ndr_push_bla
=> 1, ndr_print_bla
=> 1,
213 ndr_pull_bar
=> 1, ndr_push_bar
=> 1,
214 ndr_bar_to_rep
=> 1, ndr_rep_to_bar
=> 1});
216 my $generator = new Parse
::Pidl
::Samba4
::NDR
::Parser
();
217 $generator->ParseStructPush({
222 ELEMENTS
=> [ ]}, "ndr", "x");
223 is
($generator->{res
}, "NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
224 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
}, "NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
249 if (ndr_flags & NDR_SCALARS) {
250 NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, ndr_string_array_size(ndr, x->el1)));
251 NDR_CHECK(ndr_push_align(ndr, 4));
252 NDR_CHECK(ndr_push_mytype(ndr, NDR_SCALARS, &x->el1));
253 NDR_CHECK(ndr_push_trailer_align(ndr, 4));
255 if (ndr_flags & NDR_BUFFERS) {
259 is
(TypeFunctionName
("ndr_pull", "uint32"), "ndr_pull_uint32");
260 is
(TypeFunctionName
("ndr_pull", {TYPE
=> "ENUM", NAME
=> "bar"}), "ndr_pull_ENUM_bar");
261 is
(TypeFunctionName
("ndr_pull", {TYPE
=> "TYPEDEF", NAME
=> "bar", DATA
=> undef}), "ndr_pull_bar");
262 is
(TypeFunctionName
("ndr_push", {TYPE
=> "STRUCT", NAME
=> "bar"}), "ndr_push_STRUCT_bar");
264 # check noprint works
265 $generator = new Parse
::Pidl
::Samba4
::NDR
::Parser
();
266 $generator->ParseElementPrint({ NAME
=> "x", TYPE
=> "rt", REPRESENTATION_TYPE
=> "rt",
267 PROPERTIES
=> { noprint
=> 1},
268 LEVELS
=> [ { TYPE
=> "DATA", DATA_TYPE
=> "rt"} ]},
269 "ndr", "var", { "x" => "r->foobar" } );
270 is
($generator->{res
}, "");
272 $generator = new Parse
::Pidl
::Samba4
::NDR
::Parser
();
273 $generator->ParseElementPrint({ NAME
=> "x", TYPE
=> "rt", REPRESENTATION_TYPE
=> "rt",
275 LEVELS
=> [ { TYPE
=> "DATA", DATA_TYPE
=> "rt" }]},
276 "ndr", "var", { "x" => "r->foobar" } );
277 is
($generator->{res
}, "ndr_print_rt(ndr, \"x\", &var);\n");
279 # make sure that a print function for an element with value() set works
280 $generator = new Parse
::Pidl
::Samba4
::NDR
::Parser
();
281 $generator->ParseElementPrint({ NAME
=> "x", TYPE
=> "uint32", REPRESENTATION_TYPE
=> "uint32",
282 PROPERTIES
=> { value
=> "23" },
283 LEVELS
=> [ { TYPE
=> "DATA", DATA_TYPE
=> "uint32"} ]},
284 "ndr", "var", { "x" => "r->foobar" } );
285 is
($generator->{res
}, "ndr_print_uint32(ndr, \"x\", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?23:var);\n");
287 $generator = new Parse
::Pidl
::Samba4
::NDR
::Parser
();
288 $generator->AuthServiceStruct("bridge", "\"rot13\",\"onetimepad\"");
289 is
($generator->{res
}, "static const char * const bridge_authservice_strings[] = {
294 static const struct ndr_interface_string_array bridge_authservices = {
296 .names = bridge_authservice_strings