r7160: Initial work on an esp function wrapper generator
[samba.git] / source / 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 $scalars->{$name}{C_TYPE} if defined($scalars->{$name}) and defined($scalars->{$name}{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 => {
229                                 TYPE => "SCALAR",
230                                 NAME => $k
231                         }
232                 };
233         }
234 }
235
236 sub enum_type_fn($)
237 {
238         my $enum = shift;
239         if (util::has_property($enum->{PARENT}, "enum8bit")) {
240                 return "uint8";
241         } elsif (util::has_property($enum->{PARENT}, "v1_enum")) {
242                 return "uint32";
243         }
244         return "uint16";
245 }
246
247 sub bitmap_type_fn($)
248 {
249         my $bitmap = shift;
250
251         if (util::has_property($bitmap, "bitmap8bit")) {
252                 return "uint8";
253         } elsif (util::has_property($bitmap, "bitmap16bit")) {
254                 return "uint16";
255         } elsif (util::has_property($bitmap, "bitmap64bit")) {
256                 return "hyper";
257         }
258         return "uint32";
259 }
260
261 sub mapType($)
262 {
263         my $t = shift;
264         die("Undef passed to mapType") unless defined($t);
265         my $dt;
266
267         unless ($dt or ($dt = getType($t))) {
268                 # Best guess
269                 return "struct $t";
270         }
271         return mapScalarType($t) if ($dt->{DATA}->{TYPE} eq "SCALAR");
272         return "enum $dt->{NAME}" if ($dt->{DATA}->{TYPE} eq "ENUM");
273         return "struct $dt->{NAME}" if ($dt->{DATA}->{TYPE} eq "STRUCT");
274         return "struct $dt->{NAME}" if ($dt->{DATA}->{TYPE} eq "INTERFACE");
275         return "union $dt->{NAME}" if ($dt->{DATA}->{TYPE} eq "UNION");
276
277         if ($dt->{DATA}->{TYPE} eq "BITMAP") {
278                 return mapScalarType(bitmap_type_fn($dt->{DATA}));
279         }
280
281         die("Unknown type $dt->{DATA}->{TYPE}");
282 }
283
284 sub LoadIdl($)
285 {
286         my $idl = shift;
287
288         foreach my $x (@{$idl}) {
289                 next if $x->{TYPE} ne "INTERFACE";
290
291                 # DCOM interfaces can be types as well
292                 addType({
293                         NAME => $x->{NAME},
294                         TYPE => "TYPEDEF",
295                         DATA => $x
296                         }) if (util::has_property($x, "object"));
297
298                 foreach my $y (@{$x->{DATA}}) {
299                         addType($y) if (
300                                 $y->{TYPE} eq "TYPEDEF" 
301                              or $y->{TYPE} eq "DECLARE");
302                 }
303         }
304 }
305
306 RegisterScalars();
307
308 1;