r6516: use only one list of scalar types and make "string" just a simple scalar type...
[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                                 NDR_ALIGN       => 0
18                         },
19
20         # 1 byte types
21         "char"          => {
22                                 C_TYPE          => "char",
23                                 NDR_ALIGN       => 1
24                         },
25         "int8"          => {
26                                 C_TYPE          => "int8_t",
27                                 NDR_ALIGN       => 1
28                         },
29         "uint8"         => {
30                                 C_TYPE          => "uint8_t",
31                                 NDR_ALIGN       => 1
32                         },
33
34         # 2 byte types
35         "int16"         => {
36                                 C_TYPE          => "int16_t",
37                                 NDR_ALIGN       => 2
38                         },
39         "uint16"        => {    C_TYPE          => "uint16_t",
40                                 NDR_ALIGN       => 2
41                         },
42
43         # 4 byte types
44         "int32"         => {
45                                 C_TYPE          => "int32_t",
46                                 NDR_ALIGN       => 4
47                         },
48         "uint32"        => {    C_TYPE          => "uint32_t",
49                                 NDR_ALIGN       => 4
50                         },
51
52         # 8 byte types
53         "int64"         => {
54                                 C_TYPE          => "int64_t",
55                                 NDR_ALIGN       => 8
56                         },
57         "uint64"        => {
58                                 C_TYPE          => "uint64_t",
59                                 NDR_ALIGN       => 8
60                         },
61         "hyper"         => {
62                                 C_TYPE          => "uint64_t",
63                                 NDR_ALIGN       => 8
64                         },
65         "dlong"         => {
66                                 C_TYPE          => "int64_t",
67                                 NDR_ALIGN       => 4
68                         },
69         "udlong"        => {
70                                 C_TYPE          => "uint64_t",
71                                 NDR_ALIGN       => 4
72                         },
73         "udlongr"       => {
74                                 C_TYPE          => "uint64_t",
75                                 NDR_ALIGN       => 4
76                         },
77
78         # DATA_BLOB types
79         "DATA_BLOB"     => {
80                                 C_TYPE          => "DATA_BLOB",
81                                 NDR_ALIGN       => 4
82                         },
83
84         # string types
85         "string"        => {
86                                 C_TYPE          => "const char *",
87                                 NDR_ALIGN       => 4 #???
88                         },
89
90         # time types
91         "time_t"        => {
92                                 C_TYPE          => "time_t",
93                                 NDR_ALIGN       => 4
94                         },
95         "NTTIME"        => {
96                                 C_TYPE          => "NTTIME",
97                                 NDR_ALIGN       => 4
98                         },
99         "NTTIME_1sec"   => {
100                                 C_TYPE          => "NTTIME",
101                                 NDR_ALIGN       => 4
102                         },
103         "NTTIME_hyper"  => {
104                                 C_TYPE          => "NTTIME",
105                                 NDR_ALIGN       => 8
106                         },
107
108
109         # error code types
110         "WERROR"        => {
111                                 C_TYPE          => "WERROR",
112                                 NDR_ALIGN       => 4
113                         },
114         "NTSTATUS"      => {
115                                 C_TYPE          => "NTSTATUS",
116                                 NDR_ALIGN       => 4
117                         },
118
119         # special types
120         "nbt_string"    => {
121                                 C_TYPE          => "const char *",
122                                 NDR_ALIGN       => 4 #???
123                         },
124         "ipv4address"   => {
125                                 C_TYPE          => "const char *",
126                                 NDR_ALIGN       => 4
127                         }
128 };
129
130 # map from a IDL type to a C header type
131 sub mapScalarType($)
132 {
133         my $name = shift;
134
135         # it's a bug when a type is not in the list
136         # of known scalars or has no mapping
137         return $scalars->{$name}{C_TYPE} if defined($scalars->{$name}) and defined($scalars->{$name}{C_TYPE});
138
139         die("Unknown scalar type $name");
140 }
141
142 sub getScalarAlignment($)
143 {
144         my $name = shift;
145
146         # it's a bug when a type is not in the list
147         # of known scalars or has no mapping
148         return $scalars->{$name}{NDR_ALIGN} if defined($scalars->{$name}) and defined($scalars->{$name}{NDR_ALIGN});
149
150         die("Unknown scalar type $name");
151 }
152
153 sub addType($)
154 {
155         my $t = shift;
156         $typedefs{$t->{NAME}} = $t;
157 }
158
159 sub getType($)
160 {
161         my $t = shift;
162         return undef unless(defined($typedefs{$t}));
163         return $typedefs{$t};
164 }
165
166 sub typeIs($$)
167 {
168         my $t = shift;
169         my $tt = shift;
170
171         return 1 if (hasType($t) and getType($t)->{DATA}->{TYPE} eq $tt);
172         return 0;
173 }
174
175 sub hasType($)
176 {
177         my $t = shift;
178         return 1 if defined($typedefs{$t});
179         return 0;
180 }
181
182 sub RegisterScalars()
183 {
184         foreach my $k (keys %{$scalars}) {
185                 $typedefs{$k} = {
186                         NAME => $k,
187                         TYPE => "TYPEDEF",
188                         DATA => {
189                                 TYPE => "SCALAR",
190                                 NAME => $k
191                         }
192                 };
193         }
194 }
195
196 sub enum_type_fn($)
197 {
198         my $enum = shift;
199         if (util::has_property($enum->{PARENT}, "enum8bit")) {
200                 return "uint8";
201         } elsif (util::has_property($enum->{PARENT}, "v1_enum")) {
202                 return "uint32";
203         }
204         return "uint16";
205 }
206
207 sub bitmap_type_fn($)
208 {
209         my $bitmap = shift;
210
211         if (util::has_property($bitmap, "bitmap8bit")) {
212                 return "uint8";
213         } elsif (util::has_property($bitmap, "bitmap16bit")) {
214                 return "uint16";
215         } elsif (util::has_property($bitmap, "bitmap64bit")) {
216                 return "uint64";
217         }
218         return "uint32";
219 }
220
221 sub mapType($)
222 {
223         my $e = shift;
224         my $dt;
225
226         return "const char *" if ($e->{TYPE} =~ "string");
227
228         if ($e->{TYPE} eq "ENUM" or $e->{TYPE} eq "BITMAP") {
229                 $dt = getType($e->{PARENT}->{NAME});
230         }
231         
232         unless ($dt or $dt = getType($e->{TYPE})) {
233                 # Best guess
234                 return "struct $e->{TYPE}";
235         }
236         return mapScalarType($e->{TYPE}) if ($dt->{DATA}->{TYPE} eq "SCALAR");
237         return "enum $dt->{NAME}" if ($dt->{DATA}->{TYPE} eq "ENUM");
238         return "struct $dt->{NAME}" if ($dt->{DATA}->{TYPE} eq "STRUCT");
239         return "struct $dt->{NAME}" if ($dt->{DATA}->{TYPE} eq "INTERFACE");
240         return "union $dt->{NAME}" if ($dt->{DATA}->{TYPE} eq "UNION");
241         return mapScalarType(bitmap_type_fn($dt->{DATA})) if ($dt->{DATA}->{TYPE} eq "BITMAP");
242
243         die("Unknown type $dt->{DATA}->{TYPE}");
244 }
245
246 sub LoadIdl($)
247 {
248         my $idl = shift;
249
250         foreach my $x (@{$idl}) {
251                 next if $x->{TYPE} ne "INTERFACE";
252
253                 # DCOM interfaces can be types as well
254                 addType({
255                         NAME => $x->{NAME},
256                         TYPE => "TYPEDEF",
257                         DATA => $x
258                         }) if (util::has_property($x, "object"));
259
260                 foreach my $y (@{$x->{DATA}}) {
261                         addType($y) if (
262                                 $y->{TYPE} eq "TYPEDEF" 
263                          or $y->{TYPE} eq "DECLARE");
264                 }
265         }
266 }
267
268 RegisterScalars();
269
270 1;