pidl/NDR: give anonymous structs and unions a name
[metze/samba/wip.git] / pidl / lib / Parse / Pidl / NDR.pm
index db776ae3ef371751806d833b84e4407a74786cc1..60428c99a7ee541499ff2cf3ed362ac492bdb6be 100644 (file)
@@ -35,7 +35,7 @@ use vars qw($VERSION);
 $VERSION = '0.01';
 @ISA = qw(Exporter);
 @EXPORT = qw(GetPrevLevel GetNextLevel ContainsDeferred ContainsPipe ContainsString);
-@EXPORT_OK = qw(GetElementLevelTable ParseElement ValidElement align_type mapToScalar ParseType can_contain_deferred is_charset_array);
+@EXPORT_OK = qw(GetElementLevelTable ParseElement ReturnTypeElement ValidElement align_type mapToScalar ParseType can_contain_deferred is_charset_array);
 
 use strict;
 use Parse::Pidl qw(warning fatal);
@@ -171,6 +171,7 @@ sub GetElementLevelTable($$$)
                my $is_string = 0;
                my $is_fixed = 0;
                my $is_inline = 0;
+               my $is_to_null = 0;
 
                if ($d eq "*") {
                        $is_conformant = 1;
@@ -208,6 +209,10 @@ sub GetElementLevelTable($$$)
                        delete($e->{PROPERTIES}->{string});
                }
 
+               if (has_property($e, "to_null")) {
+                       $is_to_null = 1;
+               }
+
                push (@$order, {
                        TYPE => "ARRAY",
                        SIZE_IS => $size,
@@ -218,7 +223,8 @@ sub GetElementLevelTable($$$)
                        IS_VARYING => $is_varying,
                        IS_CONFORMANT => $is_conformant,
                        IS_FIXED => $is_fixed,
-                       IS_INLINE => $is_inline
+                       IS_INLINE => $is_inline,
+                       IS_TO_NULL => $is_to_null
                });
        }
 
@@ -515,15 +521,39 @@ sub ParseElement($$$)
        };
 }
 
+sub ParseName($)
+{
+       my ($e) = @_;
+       my $name = $e->{NAME};
+
+       return $name if defined($name);
+
+       my $parent = $e->{PARENT};
+       my $parent_name = undef;
+
+       while (not defined($parent_name)) {
+               last unless defined($parent);
+
+               $parent_name = $parent->{NAME};
+               $parent = $parent->{PARENT};
+       }
+
+       $parent_name = "global" unless defined($parent_name);
+       $name = "__pidl_".$e->{TYPE}."_".$parent_name."_".$e->{LINE};
+
+       return $name;
+}
+
 sub ParseStruct($$$)
 {
        my ($struct, $pointer_default, $ms_union) = @_;
        my @elements = ();
        my $surrounding = undef;
+       my $name = ParseName($struct);
 
        return {
                TYPE => "STRUCT",
-               NAME => $struct->{NAME},
+               NAME => $name,
                SURROUNDING_ELEMENT => undef,
                ELEMENTS => undef,
                PROPERTIES => $struct->{PROPERTIES},
@@ -554,14 +584,11 @@ sub ParseStruct($$$)
                $surrounding = $struct->{ELEMENTS}[-1];
        }
 
-       my $align = undef;
-       if ($struct->{NAME}) {
-               $align = align_type($struct->{NAME});
-       }
-               
+       my $align = align_type($name);
+
        return {
                TYPE => "STRUCT",
-               NAME => $struct->{NAME},
+               NAME => $name,
                SURROUNDING_ELEMENT => $surrounding,
                ELEMENTS => \@elements,
                PROPERTIES => $struct->{PROPERTIES},
@@ -580,10 +607,11 @@ sub ParseUnion($$)
        my $switch_type = has_property($e, "switch_type");
        unless (defined($switch_type)) { $switch_type = "uint32"; }
        if (has_property($e, "nodiscriminant")) { $switch_type = undef; }
+       my $name = ParseName($e);
 
        return {
                TYPE => "UNION",
-               NAME => $e->{NAME},
+               NAME => $name,
                SWITCH_TYPE => $switch_type,
                ELEMENTS => undef,
                PROPERTIES => $e->{PROPERTIES},
@@ -614,14 +642,11 @@ sub ParseUnion($$)
                push @elements, $t;
        }
 
-       my $align = undef;
-       if ($e->{NAME}) {
-               $align = align_type($e->{NAME});
-       }
+       my $align = align_type($name);
 
        return {
                TYPE => "UNION",
-               NAME => $e->{NAME},
+               NAME => $name,
                SWITCH_TYPE => $switch_type,
                ELEMENTS => \@elements,
                PROPERTIES => $e->{PROPERTIES},
@@ -635,10 +660,11 @@ sub ParseUnion($$)
 sub ParseEnum($$)
 {
        my ($e, $pointer_default, $ms_union) = @_;
+       my $name = ParseName($e);
 
        return {
                TYPE => "ENUM",
-               NAME => $e->{NAME},
+               NAME => $name,
                BASE_TYPE => Parse::Pidl::Typelist::enum_type_fn($e),
                ELEMENTS => $e->{ELEMENTS},
                PROPERTIES => $e->{PROPERTIES},
@@ -649,10 +675,11 @@ sub ParseEnum($$)
 sub ParseBitmap($$$)
 {
        my ($e, $pointer_default, $ms_union) = @_;
+       my $name = ParseName($e);
 
        return {
                TYPE => "BITMAP",
-               NAME => $e->{NAME},
+               NAME => $name,
                BASE_TYPE => Parse::Pidl::Typelist::bitmap_type_fn($e),
                ELEMENTS => $e->{ELEMENTS},
                PROPERTIES => $e->{PROPERTIES},
@@ -799,6 +826,25 @@ sub ParseFunction($$$$)
                };
 }
 
+sub ReturnTypeElement($)
+{
+       my ($fn) = @_;
+
+       return undef unless defined($fn->{RETURN_TYPE});
+
+       my $e = {
+               "NAME" => "result",
+               "TYPE" => $fn->{RETURN_TYPE},
+               "PROPERTIES" => undef,
+               "POINTERS" => 0,
+               "ARRAY_LEN" => [],
+               "FILE" => $fn->{FILE},
+               "LINE" => $fn->{LINE},
+       };
+
+       return ParseElement($e, 0, 0);
+}
+
 sub CheckPointerTypes($$)
 {
        my ($s,$default) = @_;
@@ -885,7 +931,8 @@ sub ParseInterface($)
                FUNCTIONS => \@functions,
                CONSTS => \@consts,
                TYPES => \@types,
-               ENDPOINTS => \@endpoints
+               ENDPOINTS => \@endpoints,
+               ORIGINAL => $idl
        };
 }
 
@@ -946,9 +993,19 @@ sub ContainsString($)
        if (property_matches($e, "flag", ".*STR_NULLTERM.*")) {
                return 1;
        }
+       if (exists($e->{LEVELS}) and $e->{LEVELS}->[0]->{TYPE} eq "ARRAY" and
+               ($e->{LEVELS}->[0]->{IS_FIXED} or $e->{LEVELS}->[0]->{IS_INLINE}) and
+               has_property($e, "charset"))
+       {
+               return 1;
+       }
+
        foreach my $l (@{$e->{LEVELS}}) {
                return 1 if ($l->{TYPE} eq "ARRAY" and $l->{IS_ZERO_TERMINATED});
        }
+       if (property_matches($e, "charset", ".*DOS.*")) {
+               return 1;
+       }
 
        return 0;
 }
@@ -1067,6 +1124,8 @@ my %property_list = (
        "noprint"               => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "ELEMENT", "PIPE"],
        "nopython"              => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"],
        "todo"                  => ["FUNCTION"],
+       "skip"                  => ["ELEMENT"],
+       "skip_noinit"           => ["ELEMENT"],
 
        # union
        "switch_is"             => ["ELEMENT"],
@@ -1102,6 +1161,7 @@ my %property_list = (
        "noheader"              => ["ELEMENT"],
        "charset"               => ["ELEMENT"],
        "length_is"             => ["ELEMENT"],
+       "to_null"               => ["ELEMENT"],
 );
 
 #####################################################################