r7161: - Add support for "aliases" for pidls scalar types and add a few aliases.
[samba.git] / source4 / build / pidl / typelist.pm
1 ###################################################
2 # Samba4 parser generator for IDL structures
3 # Copyright jelmer@samba.org 2005
4 # released under the GNU GPL
5
6 package typelist;
7
8 use strict;
9
10 my %typedefs = ();
11
12 # a list of known scalar types
13 my $scalars = {
14         # 0 byte types
15         "void"          => {
16                                 C_TYPE          => "void",
17                                 IS_REFERENCE    => 0,
18                                 NDR_ALIGN       => 0
19                         },
20
21         # 1 byte types
22         "char"          => {
23                                 C_TYPE          => "char",
24                                 IS_REFERENCE    => 0,
25                                 NDR_ALIGN       => 1
26                         },
27         "int8"          => {
28                                 C_TYPE          => "int8_t",
29                                 IS_REFERENCE    => 0,
30                                 NDR_ALIGN       => 1
31                         },
32         "uint8"         => {
33                                 C_TYPE          => "uint8_t",
34                                 IS_REFERENCE    => 0,
35                                 NDR_ALIGN       => 1
36                         },
37
38         # 2 byte types
39         "int16"         => {
40                                 C_TYPE          => "int16_t",
41                                 IS_REFERENCE    => 0,
42                                 NDR_ALIGN       => 2
43                         },
44         "uint16"        => {    C_TYPE          => "uint16_t",
45                                 IS_REFERENCE    => 0,
46                                 NDR_ALIGN       => 2
47                         },
48
49         # 4 byte types
50         "int32"         => {
51                                 C_TYPE          => "int32_t",
52                                 IS_REFERENCE    => 0,
53                                 NDR_ALIGN       => 4
54                         },
55         "uint32"        => {    C_TYPE          => "uint32_t",
56                                 IS_REFERENCE    => 0,
57                                 NDR_ALIGN       => 4
58                         },
59
60         # 8 byte types
61         "hyper"         => {
62                                 C_TYPE          => "uint64_t",
63                                 IS_REFERENCE    => 0,
64                                 NDR_ALIGN       => 8
65                         },
66         "dlong"         => {
67                                 C_TYPE          => "int64_t",
68                                 IS_REFERENCE    => 0,
69                                 NDR_ALIGN       => 4
70                         },
71         "udlong"        => {
72                                 C_TYPE          => "uint64_t",
73                                 IS_REFERENCE    => 0,
74                                 NDR_ALIGN       => 4
75                         },
76         "udlongr"       => {
77                                 C_TYPE          => "uint64_t",
78                                 IS_REFERENCE    => 0,
79                                 NDR_ALIGN       => 4
80                         },
81
82         # DATA_BLOB types
83         "DATA_BLOB"     => {
84                                 C_TYPE          => "DATA_BLOB",
85                                 IS_REFERENCE    => 0,
86                                 NDR_ALIGN       => 4
87                         },
88
89         # string types
90         "string"        => {
91                                 C_TYPE          => "const char *",
92                                 IS_REFERENCE    => 1,
93                                 NDR_ALIGN       => 4 #???
94                         },
95         "string_array"  => {
96                                 C_TYPE          => "const char **",
97                                 IS_REFERENCE    => 1,
98                                 NDR_ALIGN       => 4 #???
99                         },
100
101         # time types
102         "time_t"        => {
103                                 C_TYPE          => "time_t",
104                                 IS_REFERENCE    => 0,
105                                 NDR_ALIGN       => 4
106                         },
107         "NTTIME"        => {
108                                 C_TYPE          => "NTTIME",
109                                 IS_REFERENCE    => 0,
110                                 NDR_ALIGN       => 4
111                         },
112         "NTTIME_1sec"   => {
113                                 C_TYPE          => "NTTIME",
114                                 IS_REFERENCE    => 0,
115                                 NDR_ALIGN       => 4
116                         },
117         "NTTIME_hyper"  => {
118                                 C_TYPE          => "NTTIME",
119                                 IS_REFERENCE    => 0,
120                                 NDR_ALIGN       => 8
121                         },
122
123
124         # error code types
125         "WERROR"        => {
126                                 C_TYPE          => "WERROR",
127                                 IS_REFERENCE    => 0,
128                                 NDR_ALIGN       => 4
129                         },
130         "NTSTATUS"      => {
131                                 C_TYPE          => "NTSTATUS",
132                                 IS_REFERENCE    => 0,
133                                 NDR_ALIGN       => 4
134                         },
135
136         # special types
137         "nbt_string"    => {
138                                 C_TYPE          => "const char *",
139                                 IS_REFERENCE    => 1,
140                                 NDR_ALIGN       => 4 #???
141                         },
142         "ipv4address"   => {
143                                 C_TYPE          => "const char *",
144                                 IS_REFERENCE    => 1,
145                                 NDR_ALIGN       => 4
146                         }
147 };
148
149 # map from a IDL type to a C header type
150 sub mapScalarType($)
151 {
152         my $name = shift;
153
154         # it's a bug when a type is not in the list
155         # of known scalars or has no mapping
156         return $typedefs{$name}->{DATA}->{C_TYPE} if defined($typedefs{$name}) and defined($typedefs{$name}->{DATA}->{C_TYPE});
157
158         die("Unknown scalar type $name");
159 }
160
161 sub getScalarAlignment($)
162 {
163         my $name = shift;
164
165         # it's a bug when a type is not in the list
166         # of known scalars or has no mapping
167         return $scalars->{$name}{NDR_ALIGN} if defined($scalars->{$name}) and defined($scalars->{$name}{NDR_ALIGN});
168
169         die("Unknown scalar type $name");
170 }
171
172 sub addType($)
173 {
174         my $t = shift;
175         $typedefs{$t->{NAME}} = $t;
176 }
177
178 sub getType($)
179 {
180         my $t = shift;
181         return undef if not hasType($t);
182         return $typedefs{$t};
183 }
184
185 sub typeIs($$)
186 {
187         my $t = shift;
188         my $tt = shift;
189
190         return 1 if (hasType($t) and getType($t)->{DATA}->{TYPE} eq $tt);
191         return 0;
192 }
193
194 sub hasType($)
195 {
196         my $t = shift;
197         return 1 if defined($typedefs{$t});
198         return 0;
199 }
200
201 sub is_scalar($)
202 {
203         my $type = shift;
204
205         return 0 unless(hasType($type));
206
207         if (my $dt = getType($type)->{DATA}->{TYPE}) {
208                 return 1 if ($dt eq "SCALAR" or $dt eq "ENUM" or $dt eq "BITMAP");
209         }
210
211         return 0;
212 }
213
214 sub scalar_is_reference($)
215 {
216         my $name = shift;
217
218         return $scalars->{$name}{IS_REFERENCE} if defined($scalars->{$name}) and defined($scalars->{$name}{IS_REFERENCE});
219         return 0;
220 }
221
222 sub RegisterScalars()
223 {
224         foreach my $k (keys %{$scalars}) {
225                 $typedefs{$k} = {
226                         NAME => $k,
227                         TYPE => "TYPEDEF",
228                         DATA => $scalars->{$k}
229                 };
230                 $typedefs{$k}->{DATA}->{TYPE} = "SCALAR";
231                 $typedefs{$k}->{DATA}->{NAME} = $k;
232         }
233 }
234
235 my $aliases = {
236         "DWORD" => "uint32",
237         "int" => "int32",
238         "WORD" => "uint16",
239         "char" => "uint8",
240         "long" => "int32",
241         "short" => "int16",
242         "hyper" => "HYPER_T"
243 };
244
245 sub RegisterAliases()
246 {
247         foreach my $k (keys %{$aliases}) {
248                 $typedefs{$k} = $typedefs{$aliases->{$k}};
249         }
250 }
251
252 sub enum_type_fn($)
253 {
254         my $enum = shift;
255         if (util::has_property($enum->{PARENT}, "enum8bit")) {
256                 return "uint8";
257         } elsif (util::has_property($enum->{PARENT}, "v1_enum")) {
258                 return "uint32";
259         }
260         return "uint16";
261 }
262
263 sub bitmap_type_fn($)
264 {
265         my $bitmap = shift;
266
267         if (util::has_property($bitmap, "bitmap8bit")) {
268                 return "uint8";
269         } elsif (util::has_property($bitmap, "bitmap16bit")) {
270                 return "uint16";
271         } elsif (util::has_property($bitmap, "bitmap64bit")) {
272                 return "hyper";
273         }
274         return "uint32";
275 }
276
277 sub mapType($)
278 {
279         my $t = shift;
280         die("Undef passed to mapType") unless defined($t);
281         my $dt;
282
283         unless ($dt or ($dt = getType($t))) {
284                 # Best guess
285                 return "struct $t";
286         }
287         return mapScalarType($t) if ($dt->{DATA}->{TYPE} eq "SCALAR");
288         return "enum $dt->{NAME}" if ($dt->{DATA}->{TYPE} eq "ENUM");
289         return "struct $dt->{NAME}" if ($dt->{DATA}->{TYPE} eq "STRUCT");
290         return "struct $dt->{NAME}" if ($dt->{DATA}->{TYPE} eq "INTERFACE");
291         return "union $dt->{NAME}" if ($dt->{DATA}->{TYPE} eq "UNION");
292
293         if ($dt->{DATA}->{TYPE} eq "BITMAP") {
294                 return mapScalarType(bitmap_type_fn($dt->{DATA}));
295         }
296
297         die("Unknown type $dt->{DATA}->{TYPE}");
298 }
299
300 sub LoadIdl($)
301 {
302         my $idl = shift;
303
304         foreach my $x (@{$idl}) {
305                 next if $x->{TYPE} ne "INTERFACE";
306
307                 # DCOM interfaces can be types as well
308                 addType({
309                         NAME => $x->{NAME},
310                         TYPE => "TYPEDEF",
311                         DATA => $x
312                         }) if (util::has_property($x, "object"));
313
314                 foreach my $y (@{$x->{DATA}}) {
315                         addType($y) if (
316                                 $y->{TYPE} eq "TYPEDEF" 
317                              or $y->{TYPE} eq "DECLARE");
318                 }
319         }
320 }
321
322 RegisterScalars();
323 RegisterAliases();
324
325 1;