r7161: - Add support for "aliases" for pidls scalar types and add a few aliases.
[samba.git] / source / build / pidl / typelist.pm
index e5d6a81355ea451675d3371299249ef486ac3588..cc8504e80f4fa276e778d3d56aaa7c2fa22c38ff 100644 (file)
@@ -7,7 +7,167 @@ package typelist;
 
 use strict;
 
-my %typedefs;
+my %typedefs = ();
+
+# a list of known scalar types
+my $scalars = {
+       # 0 byte types
+       "void"          => {
+                               C_TYPE          => "void",
+                               IS_REFERENCE    => 0,
+                               NDR_ALIGN       => 0
+                       },
+
+       # 1 byte types
+       "char"          => {
+                               C_TYPE          => "char",
+                               IS_REFERENCE    => 0,
+                               NDR_ALIGN       => 1
+                       },
+       "int8"          => {
+                               C_TYPE          => "int8_t",
+                               IS_REFERENCE    => 0,
+                               NDR_ALIGN       => 1
+                       },
+       "uint8"         => {
+                               C_TYPE          => "uint8_t",
+                               IS_REFERENCE    => 0,
+                               NDR_ALIGN       => 1
+                       },
+
+       # 2 byte types
+       "int16"         => {
+                               C_TYPE          => "int16_t",
+                               IS_REFERENCE    => 0,
+                               NDR_ALIGN       => 2
+                       },
+       "uint16"        => {    C_TYPE          => "uint16_t",
+                               IS_REFERENCE    => 0,
+                               NDR_ALIGN       => 2
+                       },
+
+       # 4 byte types
+       "int32"         => {
+                               C_TYPE          => "int32_t",
+                               IS_REFERENCE    => 0,
+                               NDR_ALIGN       => 4
+                       },
+       "uint32"        => {    C_TYPE          => "uint32_t",
+                               IS_REFERENCE    => 0,
+                               NDR_ALIGN       => 4
+                       },
+
+       # 8 byte types
+       "hyper"         => {
+                               C_TYPE          => "uint64_t",
+                               IS_REFERENCE    => 0,
+                               NDR_ALIGN       => 8
+                       },
+       "dlong"         => {
+                               C_TYPE          => "int64_t",
+                               IS_REFERENCE    => 0,
+                               NDR_ALIGN       => 4
+                       },
+       "udlong"        => {
+                               C_TYPE          => "uint64_t",
+                               IS_REFERENCE    => 0,
+                               NDR_ALIGN       => 4
+                       },
+       "udlongr"       => {
+                               C_TYPE          => "uint64_t",
+                               IS_REFERENCE    => 0,
+                               NDR_ALIGN       => 4
+                       },
+
+       # DATA_BLOB types
+       "DATA_BLOB"     => {
+                               C_TYPE          => "DATA_BLOB",
+                               IS_REFERENCE    => 0,
+                               NDR_ALIGN       => 4
+                       },
+
+       # string types
+       "string"        => {
+                               C_TYPE          => "const char *",
+                               IS_REFERENCE    => 1,
+                               NDR_ALIGN       => 4 #???
+                       },
+       "string_array"  => {
+                               C_TYPE          => "const char **",
+                               IS_REFERENCE    => 1,
+                               NDR_ALIGN       => 4 #???
+                       },
+
+       # time types
+       "time_t"        => {
+                               C_TYPE          => "time_t",
+                               IS_REFERENCE    => 0,
+                               NDR_ALIGN       => 4
+                       },
+       "NTTIME"        => {
+                               C_TYPE          => "NTTIME",
+                               IS_REFERENCE    => 0,
+                               NDR_ALIGN       => 4
+                       },
+       "NTTIME_1sec"   => {
+                               C_TYPE          => "NTTIME",
+                               IS_REFERENCE    => 0,
+                               NDR_ALIGN       => 4
+                       },
+       "NTTIME_hyper"  => {
+                               C_TYPE          => "NTTIME",
+                               IS_REFERENCE    => 0,
+                               NDR_ALIGN       => 8
+                       },
+
+
+       # error code types
+       "WERROR"        => {
+                               C_TYPE          => "WERROR",
+                               IS_REFERENCE    => 0,
+                               NDR_ALIGN       => 4
+                       },
+       "NTSTATUS"      => {
+                               C_TYPE          => "NTSTATUS",
+                               IS_REFERENCE    => 0,
+                               NDR_ALIGN       => 4
+                       },
+
+       # special types
+       "nbt_string"    => {
+                               C_TYPE          => "const char *",
+                               IS_REFERENCE    => 1,
+                               NDR_ALIGN       => 4 #???
+                       },
+       "ipv4address"   => {
+                               C_TYPE          => "const char *",
+                               IS_REFERENCE    => 1,
+                               NDR_ALIGN       => 4
+                       }
+};
+
+# map from a IDL type to a C header type
+sub mapScalarType($)
+{
+       my $name = shift;
+
+       # it's a bug when a type is not in the list
+       # of known scalars or has no mapping
+       return $typedefs{$name}->{DATA}->{C_TYPE} if defined($typedefs{$name}) and defined($typedefs{$name}->{DATA}->{C_TYPE});
+
+       die("Unknown scalar type $name");
+}
+
+sub getScalarAlignment($)
+{
+       my $name = shift;
+
+       # it's a bug when a type is not in the list
+       # of known scalars or has no mapping
+       return $scalars->{$name}{NDR_ALIGN} if defined($scalars->{$name}) and defined($scalars->{$name}{NDR_ALIGN});
+
+       die("Unknown scalar type $name");
+}
 
 sub addType($)
 {
@@ -18,10 +178,19 @@ sub addType($)
 sub getType($)
 {
        my $t = shift;
-       return undef unless(defined($typedefs{$t}));
+       return undef if not hasType($t);
        return $typedefs{$t};
 }
 
+sub typeIs($$)
+{
+       my $t = shift;
+       my $tt = shift;
+
+       return 1 if (hasType($t) and getType($t)->{DATA}->{TYPE} eq $tt);
+       return 0;
+}
+
 sub hasType($)
 {
        my $t = shift;
@@ -29,28 +198,128 @@ sub hasType($)
        return 0;
 }
 
-sub RegisterPrimitives()
+sub is_scalar($)
 {
-       my @primitives = (
-               "char", "int8", "uint8", "short", "wchar_t", 
-               "int16", "uint16", "long", "int32", "uint32", 
-               "dlong", "udlong", "udlongr", "NTTIME", "NTTIME_1sec", 
-               "time_t", "DATA_BLOB", "error_status_t", "WERROR", 
-               "NTSTATUS", "boolean32", "unsigned32", "ipv4address", 
-               "hyper", "NTTIME_hyper");
-               
-       foreach my $k (@primitives) {
+       my $type = shift;
+
+       return 0 unless(hasType($type));
+
+       if (my $dt = getType($type)->{DATA}->{TYPE}) {
+               return 1 if ($dt eq "SCALAR" or $dt eq "ENUM" or $dt eq "BITMAP");
+       }
+
+       return 0;
+}
+
+sub scalar_is_reference($)
+{
+       my $name = shift;
+
+       return $scalars->{$name}{IS_REFERENCE} if defined($scalars->{$name}) and defined($scalars->{$name}{IS_REFERENCE});
+       return 0;
+}
+
+sub RegisterScalars()
+{
+       foreach my $k (keys %{$scalars}) {
                $typedefs{$k} = {
                        NAME => $k,
                        TYPE => "TYPEDEF",
-                       DATA => {
-                               TYPE => "SCALAR",
-                               NAME => $k
-                       }
+                       DATA => $scalars->{$k}
                };
+               $typedefs{$k}->{DATA}->{TYPE} = "SCALAR";
+               $typedefs{$k}->{DATA}->{NAME} = $k;
+       }
+}
+
+my $aliases = {
+       "DWORD" => "uint32",
+       "int" => "int32",
+       "WORD" => "uint16",
+       "char" => "uint8",
+       "long" => "int32",
+       "short" => "int16",
+       "hyper" => "HYPER_T"
+};
+
+sub RegisterAliases()
+{
+       foreach my $k (keys %{$aliases}) {
+               $typedefs{$k} = $typedefs{$aliases->{$k}};
+       }
+}
+
+sub enum_type_fn($)
+{
+       my $enum = shift;
+       if (util::has_property($enum->{PARENT}, "enum8bit")) {
+               return "uint8";
+       } elsif (util::has_property($enum->{PARENT}, "v1_enum")) {
+               return "uint32";
+       }
+       return "uint16";
+}
+
+sub bitmap_type_fn($)
+{
+       my $bitmap = shift;
+
+       if (util::has_property($bitmap, "bitmap8bit")) {
+               return "uint8";
+       } elsif (util::has_property($bitmap, "bitmap16bit")) {
+               return "uint16";
+       } elsif (util::has_property($bitmap, "bitmap64bit")) {
+               return "hyper";
+       }
+       return "uint32";
+}
+
+sub mapType($)
+{
+       my $t = shift;
+       die("Undef passed to mapType") unless defined($t);
+       my $dt;
+
+       unless ($dt or ($dt = getType($t))) {
+               # Best guess
+               return "struct $t";
+       }
+       return mapScalarType($t) if ($dt->{DATA}->{TYPE} eq "SCALAR");
+       return "enum $dt->{NAME}" if ($dt->{DATA}->{TYPE} eq "ENUM");
+       return "struct $dt->{NAME}" if ($dt->{DATA}->{TYPE} eq "STRUCT");
+       return "struct $dt->{NAME}" if ($dt->{DATA}->{TYPE} eq "INTERFACE");
+       return "union $dt->{NAME}" if ($dt->{DATA}->{TYPE} eq "UNION");
+
+       if ($dt->{DATA}->{TYPE} eq "BITMAP") {
+               return mapScalarType(bitmap_type_fn($dt->{DATA}));
+       }
+
+       die("Unknown type $dt->{DATA}->{TYPE}");
+}
+
+sub LoadIdl($)
+{
+       my $idl = shift;
+
+       foreach my $x (@{$idl}) {
+               next if $x->{TYPE} ne "INTERFACE";
+
+               # DCOM interfaces can be types as well
+               addType({
+                       NAME => $x->{NAME},
+                       TYPE => "TYPEDEF",
+                       DATA => $x
+                       }) if (util::has_property($x, "object"));
+
+               foreach my $y (@{$x->{DATA}}) {
+                       addType($y) if (
+                               $y->{TYPE} eq "TYPEDEF" 
+                            or $y->{TYPE} eq "DECLARE");
+               }
        }
 }
 
-RegisterPrimitives();
+RegisterScalars();
+RegisterAliases();
 
 1;