1 ###################################################
2 # Samba4 parser generator for IDL structures
3 # Copyright jelmer@samba.org 2005
4 # released under the GNU GPL
6 package Parse::Pidl::Typelist;
10 @EXPORT_OK = qw(hasType getType resolveType mapTypeName scalar_is_reference expandAlias
11 mapScalarType addType typeIs is_scalar enum_type_fn
12 bitmap_type_fn mapType typeHasBody
14 use vars qw($VERSION);
17 use Parse::Pidl::Util qw(has_property);
22 my @reference_scalars = (
23 "string", "string_array", "nbt_string",
24 "wrepl_nbt_name", "ipv4address"
27 # a list of known scalar types
34 "uint16" => "uint16_t",
36 "uint32" => "uint32_t",
37 "hyper" => "uint64_t",
39 "udlong" => "uint64_t",
40 "udlongr" => "uint64_t",
42 "DATA_BLOB" => "DATA_BLOB",
43 "string" => "const char *",
44 "string_array" => "const char **",
47 "NTTIME_1sec" => "NTTIME",
48 "NTTIME_hyper" => "NTTIME",
50 "NTSTATUS" => "NTSTATUS",
51 "COMRESULT" => "COMRESULT",
52 "nbt_string" => "const char *",
53 "wrepl_nbt_name"=> "struct nbt_name *",
54 "ipv4address" => "const char *",
58 "error_status_t" => "uint32",
59 "boolean8" => "uint8",
60 "boolean32" => "uint32",
69 "HRESULT" => "COMRESULT",
76 return $aliases{$name} if defined($aliases{$name});
81 # map from a IDL type to a C header type
86 # it's a bug when a type is not in the list
87 # of known scalars or has no mapping
88 return $scalars{$name} if defined($scalars{$name});
90 die("Unknown scalar type $name");
96 $types{$t->{NAME}} = $t;
103 if (not hasType($ctype)) {
104 # assume struct typedef
105 return { TYPE => "TYPEDEF", NAME => $ctype, DATA => { TYPE => "STRUCT" } };
107 return getType($ctype);
116 return ($t) if (ref($t) eq "HASH" and not defined($t->{NAME}));
117 return undef if not hasType($t);
118 return $types{$t->{NAME}} if (ref($t) eq "HASH");
126 if (ref($t) eq "HASH") {
127 return 1 if ($t->{TYPE} eq $tt);
130 return 1 if (hasType($t) and getType($t)->{TYPE} eq "TYPEDEF" and
131 getType($t)->{DATA}->{TYPE} eq $tt);
138 if (ref($t) eq "HASH") {
139 return 1 if (not defined($t->{NAME}));
140 return 1 if (defined($types{$t->{NAME}}) and
141 $types{$t->{NAME}}->{TYPE} eq $t->{TYPE});
144 return 1 if defined($types{$t});
153 return 1 if (ref($type) eq "HASH" and
154 ($type->{TYPE} eq "SCALAR" or $type->{TYPE} eq "ENUM" or
155 $type->{TYPE} eq "BITMAP"));
157 if (my $dt = getType($type)) {
158 return is_scalar($dt->{DATA}) if ($dt->{TYPE} eq "TYPEDEF");
159 return 1 if ($dt->{TYPE} eq "SCALAR" or $dt->{TYPE} eq "ENUM" or
160 $dt->{TYPE} eq "BITMAP");
166 sub scalar_is_reference($)
170 return 1 if (grep(/^$name$/, @reference_scalars));
174 sub RegisterScalars()
176 foreach (keys %scalars) {
192 $enum->{TYPE} eq "ENUM" or die("not an enum");
194 # for typedef enum { } we need to check $enum->{PARENT}
195 if (has_property($enum, "enum8bit")) {
197 } elsif (has_property($enum, "enum16bit")) {
199 } elsif (has_property($enum, "v1_enum")) {
201 } elsif (has_property($enum->{PARENT}, "enum8bit")) {
203 } elsif (has_property($enum->{PARENT}, "enum16bit")) {
205 } elsif (has_property($enum->{PARENT}, "v1_enum")) {
211 sub bitmap_type_fn($)
215 $bitmap->{TYPE} eq "BITMAP" or die("not a bitmap");
217 if (has_property($bitmap, "bitmap8bit")) {
219 } elsif (has_property($bitmap, "bitmap16bit")) {
221 } elsif (has_property($bitmap, "bitmap64bit")) {
232 if ($e->{TYPE} eq "TYPEDEF") {
233 return 0 unless(defined($e->{DATA}));
234 return typeHasBody($e->{DATA});
237 return defined($e->{ELEMENTS});
245 return mapType($t->{DATA}, $n) if ($t->{TYPE} eq "TYPEDEF");
246 return mapScalarType($n) if ($t->{TYPE} eq "SCALAR");
247 return "enum $n" if ($t->{TYPE} eq "ENUM");
248 return "struct $n" if ($t->{TYPE} eq "STRUCT");
249 return "union $n" if ($t->{TYPE} eq "UNION");
250 return mapScalarType(bitmap_type_fn($t)) if ($t->{TYPE} eq "BITMAP");
251 die("Unknown type $t->{TYPE}");
257 return "void" unless defined($t);
259 $t = expandAlias($t);
261 unless ($dt or ($dt = getType($t))) {
266 return mapType($dt, $dt->{NAME});
273 foreach my $x (@{$idl}) {
274 next if $x->{TYPE} ne "INTERFACE";
276 foreach my $y (@{$x->{DATA}}) {
278 $y->{TYPE} eq "TYPEDEF"
279 or $y->{TYPE} eq "UNION"
280 or $y->{TYPE} eq "STRUCT"
281 or $y->{TYPE} eq "ENUM"
282 or $y->{TYPE} eq "BITMAP");
287 sub GenerateTypeLib()
289 return Parse::Pidl::Util::MyDumper(\%types);