pidl: Avoid accidently filling in empty body for types without body.
[ira/wip.git] / source / pidl / tests / ndr.pl
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;
6
7 use Test::More tests => 40;
8 use FindBin qw($RealBin);
9 use lib "$RealBin";
10 use Util;
11 use Parse::Pidl::Util qw(MyDumper);
12 use Parse::Pidl::NDR qw(GetElementLevelTable ParseElement align_type mapToScalar ParseType can_contain_deferred);
13
14 # Case 1
15
16 my $e = {
17         'FILE' => 'foo.idl',
18         'NAME' => 'v',
19         'PROPERTIES' => {},
20         'POINTERS' => 0,
21         'TYPE' => 'uint8',
22         'PARENT' => { TYPE => 'STRUCT' },
23         'LINE' => 42 };
24
25 is_deeply(GetElementLevelTable($e), [
26         {
27                 'IS_DEFERRED' => 0,
28                 'LEVEL_INDEX' => 0,
29                 'DATA_TYPE' => 'uint8',
30                 'CONTAINS_DEFERRED' => 0,
31                 'TYPE' => 'DATA',
32                 'IS_SURROUNDING' => 0,
33         }
34 ]);
35
36 my $ne = ParseElement($e, undef);
37 is($ne->{ORIGINAL}, $e);
38 is($ne->{NAME}, "v");
39 is($ne->{ALIGN}, 1);
40 is($ne->{TYPE}, "uint8");
41 is_deeply($ne->{LEVELS},  [
42         {
43                 'IS_DEFERRED' => 0,
44                 'LEVEL_INDEX' => 0,
45                 'DATA_TYPE' => 'uint8',
46                 'CONTAINS_DEFERRED' => 0,
47                 'TYPE' => 'DATA',
48                 'IS_SURROUNDING' => 0,
49         }
50 ]);
51
52 # Case 2 : pointers
53 #
54 $e = {
55         'FILE' => 'foo.idl',
56         'NAME' => 'v',
57         'PROPERTIES' => {"unique" => 1},
58         'POINTERS' => 1,
59         'PARENT' => { TYPE => 'STRUCT' },
60         'TYPE' => 'uint8',
61         'LINE' => 42 };
62
63 is_deeply(GetElementLevelTable($e), [
64         {
65                 LEVEL_INDEX => 0,
66                 IS_DEFERRED => 0,
67                 TYPE => 'POINTER',
68                 POINTER_TYPE => "unique",
69                 POINTER_INDEX => 0,
70                 LEVEL => 'EMBEDDED'
71         },
72         {
73                 'IS_DEFERRED' => 1,
74                 'LEVEL_INDEX' => 1,
75                 'DATA_TYPE' => 'uint8',
76                 'CONTAINS_DEFERRED' => 0,
77                 'TYPE' => 'DATA',
78                 'IS_SURROUNDING' => 0,
79         }
80 ]);
81
82 # Case 3 : double pointers
83 #
84 $e = {
85         'FILE' => 'foo.idl',
86         'NAME' => 'v',
87         'PROPERTIES' => {"unique" => 1},
88         'POINTERS' => 2,
89         'TYPE' => 'uint8',
90         'PARENT' => { TYPE => 'STRUCT' },
91         'LINE' => 42 };
92
93 is_deeply(GetElementLevelTable($e), [
94         {
95                 LEVEL_INDEX => 0,
96                 IS_DEFERRED => 0,
97                 TYPE => 'POINTER',
98                 POINTER_TYPE => "unique",
99                 POINTER_INDEX => 0,
100                 LEVEL => 'EMBEDDED'
101         },
102         {
103                 LEVEL_INDEX => 1,
104                 IS_DEFERRED => 1,
105                 TYPE => 'POINTER',
106                 POINTER_TYPE => "unique",
107                 POINTER_INDEX => 1,
108                 LEVEL => 'EMBEDDED'
109         },
110         {
111                 'IS_DEFERRED' => 1,
112                 'LEVEL_INDEX' => 2,
113                 'DATA_TYPE' => 'uint8',
114                 'CONTAINS_DEFERRED' => 0,
115                 'TYPE' => 'DATA',
116                 'IS_SURROUNDING' => 0,
117         }
118 ]);
119
120 # Case 3 : ref pointers
121 #
122 $e = {
123         'FILE' => 'foo.idl',
124         'NAME' => 'v',
125         'PROPERTIES' => {"ref" => 1},
126         'POINTERS' => 1,
127         'TYPE' => 'uint8',
128         'PARENT' => { TYPE => 'STRUCT' },
129         'LINE' => 42 };
130
131 is_deeply(GetElementLevelTable($e), [
132         {
133                 LEVEL_INDEX => 0,
134                 IS_DEFERRED => 0,
135                 TYPE => 'POINTER',
136                 POINTER_TYPE => "ref",
137                 POINTER_INDEX => 0,
138                 LEVEL => 'EMBEDDED'
139         },
140         {
141                 'IS_DEFERRED' => 1,
142                 'LEVEL_INDEX' => 1,
143                 'DATA_TYPE' => 'uint8',
144                 'CONTAINS_DEFERRED' => 0,
145                 'TYPE' => 'DATA',
146                 'IS_SURROUNDING' => 0,
147         }
148 ]);
149
150
151 # Case 4 : top-level ref pointers
152 #
153 $e = {
154         'FILE' => 'foo.idl',
155         'NAME' => 'v',
156         'PROPERTIES' => {"ref" => 1},
157         'POINTERS' => 1,
158         'TYPE' => 'uint8',
159         'PARENT' => { TYPE => 'FUNCTION' },
160         'LINE' => 42 };
161
162 is_deeply(GetElementLevelTable($e), [
163         {
164                 LEVEL_INDEX => 0,
165                 IS_DEFERRED => 0,
166                 TYPE => 'POINTER',
167                 POINTER_TYPE => "ref",
168                 POINTER_INDEX => 0,
169                 LEVEL => 'TOP'
170         },
171         {
172                 'IS_DEFERRED' => 0,
173                 'LEVEL_INDEX' => 1,
174                 'DATA_TYPE' => 'uint8',
175                 'CONTAINS_DEFERRED' => 0,
176                 'TYPE' => 'DATA',
177                 'IS_SURROUNDING' => 0,
178         }
179 ]);
180
181 # representation_type
182 $e = {
183         'FILE' => 'foo.idl',
184         'NAME' => 'v',
185         'PROPERTIES' => { represent_as => "bar" },
186         'POINTERS' => 0,
187         'TYPE' => 'uint8',
188         'PARENT' => { TYPE => 'STRUCT' },
189         'LINE' => 42 };
190
191 $ne = ParseElement($e, undef);
192 is($ne->{REPRESENTATION_TYPE}, "bar");
193
194 # representation_type
195 $e = {
196         'FILE' => 'foo.idl',
197         'NAME' => 'v',
198         'PROPERTIES' => { },
199         'POINTERS' => 0,
200         'TYPE' => 'uint8',
201         'PARENT' => { TYPE => 'STRUCT' },
202         'LINE' => 42 };
203
204 $ne = ParseElement($e, undef);
205 is($ne->{REPRESENTATION_TYPE}, "uint8");
206
207 is(align_type("hyper"), 8);
208 is(align_type("uint32"), 4);
209 is(align_type("uint16"), 2);
210 is(align_type("uint8"), 1);
211 is(align_type({ TYPE => "STRUCT", "NAME" => "bla", 
212                             ELEMENTS => [ { TYPE => "uint16" } ] }), 4);
213 is(align_type({ TYPE => "STRUCT", 
214                             ELEMENTS => [ { TYPE => "hyper" } ] }), 8);
215 is(align_type({ TYPE => "TYPEDEF", DATA => { 
216                                 TYPE => "STRUCT", 
217                             ELEMENTS => [ { TYPE => "hyper" } ] }}), 8);
218 # typedef of struct without body
219 is(align_type({ TYPE => "TYPEDEF", DATA => { 
220                                 TYPE => "STRUCT", ELEMENTS => undef }}), 4);
221 # struct without body
222 is(align_type({ TYPE => "STRUCT", ELEMENTS => undef }), 4);
223 # empty struct
224 is(align_type({ TYPE => "STRUCT", ELEMENTS => [] }), 1);
225 is(align_type({ TYPE => "STRUCT", "NAME" => "bla", 
226                             ELEMENTS => [ { TYPE => "uint8" } ] }), 4);
227
228 is(mapToScalar("someverymuchnotexistingtype"), undef);
229 is(mapToScalar("uint32"), "uint32");
230 is(mapToScalar({TYPE => "ENUM", PARENT => { PROPERTIES => { enum8bit => 1 } } }), "uint8");
231 is(mapToScalar({TYPE => "BITMAP", PROPERTIES => { bitmap64bit => 1 } }),
232         "hyper");
233 is(mapToScalar({TYPE => "TYPEDEF", DATA => {TYPE => "ENUM", PARENT => { PROPERTIES => { enum8bit => 1 } } }}), "uint8");
234
235 my $t;
236 $t = {
237         TYPE => "STRUCT",
238         NAME => "foo",
239         SURROUNDING_ELEMENT => undef,
240         ELEMENTS => undef,
241         PROPERTIES => undef,
242         ORIGINAL => {
243                 TYPE => "STRUCT",
244                 NAME => "foo"
245         },
246         ALIGN => undef
247 };
248 is_deeply(ParseType($t->{ORIGINAL}, "ref"), $t); 
249
250 $t = {
251         TYPE => "UNION",
252         NAME => "foo",
253         SWITCH_TYPE => "uint32",
254         ELEMENTS => undef,
255         PROPERTIES => undef,
256         HAS_DEFAULT => 0,
257         ORIGINAL => {
258                 TYPE => "UNION",
259                 NAME => "foo"
260         }
261 };
262 is_deeply(ParseType($t->{ORIGINAL}, "ref"), $t); 
263
264 ok(not can_contain_deferred("uint32"));
265 ok(can_contain_deferred("some_unknown_type"));
266 ok(can_contain_deferred({ TYPE => "STRUCT", 
267                 ELEMENTS => [ { TYPE => "uint32", POINTERS => 40 } ]}));
268 ok(can_contain_deferred({ TYPE => "TYPEDEF", 
269                         DATA => { TYPE => "STRUCT", 
270                 ELEMENTS => [ { TYPE => "uint32", POINTERS => 40 } ]}}));
271 ok(not can_contain_deferred({ TYPE => "STRUCT", 
272                 ELEMENTS => [ { TYPE => "uint32" } ]}));
273 ok(not can_contain_deferred({ TYPE => "TYPEDEF",
274                         DATA => { TYPE => "STRUCT", 
275                 ELEMENTS => [ { TYPE => "uint32" } ]}}));
276 ok(can_contain_deferred({ TYPE => "STRUCT", 
277                 ELEMENTS => [ { TYPE => "someunknowntype" } ]}));
278 # Make sure the elements for a enum without body aren't filled in
279 ok(not defined(ParseType({TYPE => "ENUM", NAME => "foo" }, "ref")->{ELEMENTS}));
280 # Make sure the elements for a bitmap without body aren't filled in
281 ok(not defined(ParseType({TYPE => "BITMAP", NAME => "foo" }, "ref")->{ELEMENTS}));
282 # Make sure the elements for a union without body aren't filled in
283 ok(not defined(ParseType({TYPE => "UNION", NAME => "foo" }, "ref")->{ELEMENTS}));