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 mapTypeSpecifier scalar_is_reference expandAlias
11 mapScalarType addType typeIs is_signed is_scalar enum_type_fn
12 bitmap_type_fn mapType typeHasBody is_fixed_size_scalar
14 use vars qw($VERSION);
17 use Parse::Pidl::Util qw(has_property);
23 my @reference_scalars = (
24 "string", "string_array", "nbt_string", "dns_string",
25 "wrepl_nbt_name", "dnsp_name", "dnsp_string",
26 "ipv4address", "ipv6address"
29 my @non_fixed_size_scalars = (
30 "string", "string_array", "nbt_string", "dns_string",
31 "wrepl_nbt_name", "dnsp_name", "dnsp_string"
34 # a list of known scalar types
41 "uint16" => "uint16_t",
42 "int1632" => "int16_t",
43 "uint1632" => "uint16_t",
45 "uint32" => "uint32_t",
46 "int3264" => "int32_t",
47 "uint3264" => "uint32_t",
48 "hyper" => "uint64_t",
51 "udlong" => "uint64_t",
52 "udlongr" => "uint64_t",
55 "DATA_BLOB" => "DATA_BLOB",
56 "string" => "const char *",
57 "string_array" => "const char **",
62 "NTTIME_1sec" => "NTTIME",
63 "NTTIME_hyper" => "NTTIME",
65 "HRESULT" => "HRESULT",
66 "NTSTATUS" => "NTSTATUS",
67 "COMRESULT" => "COMRESULT",
68 "dns_string" => "const char *",
69 "nbt_string" => "const char *",
70 "wrepl_nbt_name"=> "struct nbt_name *",
71 "ipv4address" => "const char *",
72 "ipv6address" => "const char *",
73 "dnsp_name" => "const char *",
74 "dnsp_string" => "const char *",
75 "libndr_flags" => "libndr_flags",
76 "ndr_flags_type"=> "ndr_flags_type",
80 "error_status_t" => "uint32",
81 "boolean8" => "uint8",
82 "boolean32" => "uint32",
94 my %format_specifiers = (
96 "int8_t", => "\"PRId8\"",
97 "int16_t", => "\"PRId16\"",
98 "int32_t", => "\"PRId32\"",
99 "int64_t", => "\"PRId64\"",
100 "uint8_t", => "\"PRIu8\"",
101 "uint16_t", => "\"PRIu16\"",
102 "uint32_t", => "\"PRIu32\"",
103 "uint64_t", => "\"PRIu64\""
110 return $aliases{$name} if defined($aliases{$name});
115 # map from a IDL type to a C header type
120 # it's a bug when a type is not in the list
121 # of known scalars or has no mapping
122 return $scalars{$name} if defined($scalars{$name});
124 die("Unknown scalar type $name");
130 $types{$t->{NAME}} = $t;
137 if (not hasType($ctype)) {
138 # assume struct typedef
139 return { TYPE => "TYPEDEF", NAME => $ctype, DATA => { TYPE => "STRUCT" } };
141 return getType($ctype);
150 return ($t) if (ref($t) eq "HASH" and not defined($t->{NAME}));
151 return undef if not hasType($t);
152 return $types{$t->{NAME}} if (ref($t) eq "HASH");
161 if (ref($t) eq "HASH") {
162 return 1 if ($t->{TYPE} eq "TYPEDEF" and $t->{DATA}->{TYPE} eq $tt);
163 return 1 if ($t->{TYPE} eq $tt);
166 if (hasType($t) and getType($t)->{TYPE} eq "TYPEDEF") {
167 return typeIs(getType($t)->{DATA}, $tt);
175 if (ref($t) eq "HASH") {
176 return 1 if (not defined($t->{NAME}));
177 return 1 if (defined($types{$t->{NAME}}) and
178 $types{$t->{NAME}}->{TYPE} eq $t->{TYPE});
181 return 1 if defined($types{$t});
203 return 1 if (ref($type) eq "HASH" and
204 ($type->{TYPE} eq "SCALAR" or $type->{TYPE} eq "ENUM" or
205 $type->{TYPE} eq "BITMAP"));
207 if (my $dt = getType($type)) {
208 return is_scalar($dt->{DATA}) if ($dt->{TYPE} eq "TYPEDEF");
209 return 1 if ($dt->{TYPE} eq "SCALAR" or $dt->{TYPE} eq "ENUM" or
210 $dt->{TYPE} eq "BITMAP");
216 sub is_fixed_size_scalar($)
220 return 0 unless is_scalar($name);
221 return 0 if (grep(/^$name$/, @non_fixed_size_scalars));
225 sub scalar_is_reference($)
229 return 1 if (grep(/^$name$/, @reference_scalars));
233 sub RegisterScalars()
235 foreach (keys %scalars) {
239 BASEFILE => "<builtin>",
252 $enum->{TYPE} eq "ENUM" or die("not an enum");
254 # for typedef enum { } we need to check $enum->{PARENT}
255 if (has_property($enum, "enum8bit")) {
257 } elsif (has_property($enum, "enum16bit")) {
259 } elsif (has_property($enum, "v1_enum")) {
261 } elsif (has_property($enum->{PARENT}, "enum8bit")) {
263 } elsif (has_property($enum->{PARENT}, "enum16bit")) {
265 } elsif (has_property($enum->{PARENT}, "v1_enum")) {
271 sub bitmap_type_fn($)
275 $bitmap->{TYPE} eq "BITMAP" or die("not a bitmap");
277 if (has_property($bitmap, "bitmap8bit")) {
279 } elsif (has_property($bitmap, "bitmap16bit")) {
281 } elsif (has_property($bitmap, "bitmap64bit")) {
292 if ($e->{TYPE} eq "TYPEDEF") {
293 return 0 unless(defined($e->{DATA}));
294 return typeHasBody($e->{DATA});
297 return defined($e->{ELEMENTS});
305 return mapType($t->{DATA}, $n) if ($t->{TYPE} eq "TYPEDEF");
306 return mapScalarType($n) if ($t->{TYPE} eq "SCALAR");
307 return "enum $n" if ($t->{TYPE} eq "ENUM");
308 return "struct $n" if ($t->{TYPE} eq "STRUCT" or $t->{TYPE} eq "INTERFACE");
309 return "union $n" if ($t->{TYPE} eq "UNION");
310 return mapScalarType(bitmap_type_fn($t)) if ($t->{TYPE} eq "BITMAP");
311 return "struct $n" if ($t->{TYPE} eq "PIPE");
312 die("Unknown type $t->{TYPE}");
318 return "void" unless defined($t);
320 $t = expandAlias($t);
322 if ($dt = getType($t)) {
323 return mapType($dt, $dt->{NAME});
324 } elsif (ref($t) eq "HASH" and defined($t->{NAME})) {
325 return mapType($t, $t->{NAME});
333 sub mapTypeSpecifier($)
336 return undef unless defined($t);
338 return $format_specifiers{$t};
344 my $basename = shift;
346 foreach my $x (@{$idl}) {
347 next if $x->{TYPE} ne "INTERFACE";
349 # DCOM interfaces can be types as well
354 BASEFILE => $basename,
355 }) if (has_property($x, "object"));
357 foreach my $y (@{$x->{DATA}}) {
358 if ($y->{TYPE} eq "TYPEDEF"
359 or $y->{TYPE} eq "UNION"
360 or $y->{TYPE} eq "STRUCT"
361 or $y->{TYPE} eq "ENUM"
362 or $y->{TYPE} eq "BITMAP"
363 or $y->{TYPE} eq "PIPE") {
364 $y->{BASEFILE} = $basename;
371 sub GenerateTypeLib()
373 return Parse::Pidl::Util::MyDumper(\%types);