r21584: Support for tagged types has landed!
authorJelmer Vernooij <jelmer@samba.org>
Wed, 28 Feb 2007 13:25:53 +0000 (13:25 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:49:00 +0000 (14:49 -0500)
It's now possible to use "struct foo" without a typedef in IDL files.

echo_info4 is the first type that's been converted.

source/librpc/idl/echo.idl
source/pidl/README
source/pidl/lib/Parse/Pidl/NDR.pm
source/pidl/lib/Parse/Pidl/Samba4/EJS.pm
source/pidl/lib/Parse/Pidl/Samba4/Header.pm
source/pidl/tests/header.pl
source/pidl/tests/ndr.pl
source/pidl/tests/typelist.pl

index fa030be761c8557db970861a9379f37b95e07eaa..5ea37f1ac1940cc22d0801f87b8075f15154826e 100644 (file)
@@ -50,9 +50,9 @@ interface rpcecho
                uint32 v;
        } echo_info3;
 
-       typedef struct {
+       struct echo_info4 {
                hyper v;
-       } echo_info4;
+       };
 
        typedef struct {
                uint8 v1;
@@ -66,14 +66,14 @@ interface rpcecho
 
        typedef struct {
                uint8 v1;
-               echo_info4 info4;
+               struct echo_info4 info4;
        } echo_info7;
 
        typedef [switch_type(uint16)] union {
                [case(1)]  echo_info1 info1;
                [case(2)]  echo_info2 info2;
                [case(3)]  echo_info3 info3;
-               [case(4)]  echo_info4 info4;
+               [case(4)]  struct echo_info4 info4;
                [case(5)]  echo_info5 info5;
                [case(6)]  echo_info6 info6;
                [case(7)]  echo_info7 info7;
index 88569938163b2dc70fa2eb3d5f57d2ca352e4a49..5bf7752da977444665dfd382b91fbad98ba137f9 100644 (file)
@@ -4,7 +4,7 @@ This directory contains the source code of the pidl (Perl IDL)
 compiler for Samba 4. 
 
 The main sources for pidl are available by Subversion on
-svn://svn.samba.org/samba/branches/SAMBA_4_0/source/pidl
+svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/pidl
 
 Pidl works by building a parse tree from a .pidl file (a simple 
 dump of it's internal parse tree) or a .idl file 
index 998b19aabf110ed465502972326bcb5cd36306ca..f05e3120c761c138f1faa16feba7f40740f56b9d 100644 (file)
@@ -35,7 +35,7 @@ use vars qw($VERSION);
 $VERSION = '0.01';
 @ISA = qw(Exporter);
 @EXPORT = qw(GetPrevLevel GetNextLevel ContainsDeferred ContainsString);
-@EXPORT_OK = qw(GetElementLevelTable ParseElement ValidElement align_type mapToScalar);
+@EXPORT_OK = qw(GetElementLevelTable ParseElement ValidElement align_type mapToScalar ParseType);
 
 use strict;
 use Parse::Pidl qw(warning fatal);
@@ -499,6 +499,7 @@ sub ParseType($$)
        my ($d, $pointer_default) = @_;
 
        if ($d->{TYPE} eq "STRUCT" or $d->{TYPE} eq "UNION") {
+               return $d if (not defined($d->{ELEMENTS}));
                CheckPointerTypes($d, $pointer_default);
        }
 
index c254bfad38e240dc03856be79ed66d33c25e7c32..054074297bc51fb680ed8d7aa6e163a5a05177a5 100644 (file)
@@ -426,14 +426,7 @@ sub EjsPushScalar($$$$$)
                                        $var = get_pointer_to($var);
                        }
 
-               my $t;
-               if (ref($e->{TYPE}) eq "HASH") {
-                       $t = "$e->{TYPE}->{TYPE}_$e->{TYPE}->{NAME}";
-               } else {
-                       $t = $e->{TYPE};
-               }
-
-               pidl "NDR_CHECK(ejs_push_$t(ejs, v, $name, $var));";
+               pidl "NDR_CHECK(".TypeFunctionName("ejs_push", $e->{TYPE})."(ejs, v, $name, $var));";
        }
 }
 
@@ -619,21 +612,22 @@ sub EjsTypePushFunction($$)
        my ($d, $name) = @_;
        return if (has_property($d, "noejs"));
 
-       if ($d->{TYPE} eq "TYPEDEF") {
-               EjsTypePushFunction($d->{DATA}, $name);
-               return;
-       }
-
-       if ($d->{TYPE} eq "STRUCT") {
-               fn_declare($d, "NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const struct $name *r)");
-       } elsif ($d->{TYPE} eq "UNION") {
-               fn_declare($d, "NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const union $name *r)");
-       } elsif ($d->{TYPE} eq "ENUM") {
-               fn_declare($d, "NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const enum $name *r)");
-       } elsif ($d->{TYPE} eq "BITMAP") {
-               my($type_decl) = Parse::Pidl::Typelist::mapTypeName($d->{BASE_TYPE});
-               fn_declare($d, "NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const $type_decl *r)");
-       }
+       my $var = undef;
+       my $dt = $d;
+       if ($dt->{TYPE} eq "TYPEDEF") {
+               $dt = $dt->{DATA};
+       }
+       if ($dt->{TYPE} eq "STRUCT") {
+               $var = "const struct $name *r";
+       } elsif ($dt->{TYPE} eq "UNION") {
+               $var = "const union $name *r";
+       } elsif ($dt->{TYPE} eq "ENUM") {
+               $var = "const enum $name *r";
+       } elsif ($dt->{TYPE} eq "BITMAP") {
+               my($type_decl) = Parse::Pidl::Typelist::mapTypeName($dt->{BASE_TYPE});
+               $var = "const $type_decl *r";
+       }
+       fn_declare($d, "NTSTATUS ".TypeFunctionName("ejs_push", $d) . "(struct ejs_rpc *ejs, struct MprVar *v, const char *name, $var)");
        pidl "{";
        indent;
        EjsTypePush($d, "r");
@@ -644,6 +638,7 @@ sub EjsTypePushFunction($$)
 
 sub EjsTypePush($$)
 {
+       sub EjsTypePush($$);
        my ($d, $varname) = @_;
 
        if ($d->{TYPE} eq 'STRUCT') {
@@ -654,6 +649,8 @@ sub EjsTypePush($$)
                EjsEnumPush($d, $varname);
        } elsif ($d->{TYPE} eq 'BITMAP') {
                EjsBitmapPush($d, $varname);
+       } elsif ($d->{TYPE} eq 'TYPEDEF') {
+               EjsTypePush($d->{DATA}, $varname);
        } else {
                warn "Unhandled push $varname of type $d->{TYPE}";
        }
@@ -677,8 +674,7 @@ sub EjsPushFunction($)
        }
 
        if ($d->{RETURN_TYPE}) {
-               my $t = $d->{RETURN_TYPE};
-               pidl "NDR_CHECK(ejs_push_$t(ejs, v, \"result\", &r->out.result));";
+               pidl "NDR_CHECK(".TypeFunctionName("ejs_push", $d->{RETURN_TYPE})."(ejs, v, \"result\", &r->out.result));";
        }
 
        pidl "return NT_STATUS_OK;";
index 11ecc170011808f5baf287424944da2485532cee..2eddf22b0590828bf28acd646dce929cdc7f76a2 100644 (file)
@@ -57,7 +57,11 @@ sub HeaderElement($)
        if (has_property($element, "represent_as")) {
                pidl mapTypeName($element->{PROPERTIES}->{represent_as})." ";
        } else {
-               HeaderType($element, $element->{TYPE}, "");
+               if (ref($element->{TYPE}) eq "HASH") {
+                       HeaderType($element, $element->{TYPE}, $element->{TYPE}->{NAME});
+               } else {
+                       HeaderType($element, $element->{TYPE}, "");
+               }
                pidl " ";
                my $numstar = $element->{POINTERS};
                if ($numstar >= 1) {
@@ -90,14 +94,14 @@ sub HeaderElement($)
 sub HeaderStruct($$)
 {
     my($struct,$name) = @_;
-       pidl "struct $name {\n";
+       pidl "struct $name";
+    return if (not defined($struct->{ELEMENTS}));
+       pidl " {\n";
     $tab_depth++;
     my $el_count=0;
-    if (defined $struct->{ELEMENTS}) {
-               foreach (@{$struct->{ELEMENTS}}) {
-                   HeaderElement($_);
-                   $el_count++;
-               }
+       foreach (@{$struct->{ELEMENTS}}) {
+               HeaderElement($_);
+               $el_count++;
     }
     if ($el_count == 0) {
            # some compilers can't handle empty structures
@@ -174,7 +178,9 @@ sub HeaderUnion($$)
        my($union,$name) = @_;
        my %done = ();
 
-       pidl "union $name {\n";
+       pidl "union $name";
+       return if (not defined($union->{ELEMENTS}));
+       pidl " {\n";
        $tab_depth++;
        foreach my $e (@{$union->{ELEMENTS}}) {
                if ($e->{TYPE} ne "EMPTY") {
index 3dae33ae6c52c9ca6a581b5c64e05a59d441a268..7092eb0d148777ac223bac2515cfa769b010d91f 100755 (executable)
@@ -4,7 +4,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 10;
+use Test::More tests => 12;
 use FindBin qw($RealBin);
 use lib "$RealBin";
 use Util;
@@ -36,3 +36,9 @@ like(parse_idl("interface x { void foo ([in,out] uint32 x); };"),
 like(parse_idl("interface x { void foo (uint32 x); };"), qr/struct foo.*{.*struct\s+{\s+uint32_t x;\s+} in;\s+struct\s+{\s+uint32_t x;\s+} out;.*};/sm, "fn with no props implies in,out");
 like(parse_idl("interface p { struct x { int y; }; };"),
      qr/struct x.*{.*int32_t y;.*}.*;/sm, "interface member generated properly");
+
+like(parse_idl("interface p { struct x { struct y z; }; };"),
+     qr/struct x.*{.*struct y z;.*}.*;/sm, "tagged type struct member");
+
+like(parse_idl("interface p { struct x { union y z; }; };"),
+     qr/struct x.*{.*union y z;.*}.*;/sm, "tagged type union member");
index 17003d59c46f2d2438a4fb7ac8521116784ef989..8245f768e8463a1d86487567bf430187631ca05a 100755 (executable)
@@ -4,12 +4,12 @@
 use strict;
 use warnings;
 
-use Test::More tests => 25;
+use Test::More tests => 26;
 use FindBin qw($RealBin);
 use lib "$RealBin";
 use Util;
 use Parse::Pidl::Util qw(MyDumper);
-use Parse::Pidl::NDR qw(GetElementLevelTable ParseElement align_type mapToScalar);
+use Parse::Pidl::NDR qw(GetElementLevelTable ParseElement align_type mapToScalar ParseType);
 
 # Case 1
 
@@ -224,3 +224,6 @@ is(mapToScalar({TYPE => "ENUM", PARENT => { PROPERTIES => { enum8bit => 1 } } })
 is(mapToScalar({TYPE => "BITMAP", PROPERTIES => { bitmap64bit => 1 } }),
        "hyper");
 is(mapToScalar({TYPE => "TYPEDEF", DATA => {TYPE => "ENUM", PARENT => { PROPERTIES => { enum8bit => 1 } } }}), "uint8");
+
+is_deeply(ParseType({TYPE => "STRUCT", NAME => "foo" }, "ref"), 
+       {TYPE => "STRUCT", NAME => "foo" });
index 376bd208f096241dd5e9255e75d837268d3afb2e..c5c409a5259b9a72adef1338b718f2992848bb24 100755 (executable)
@@ -4,7 +4,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 52;
+use Test::More tests => 53;
 use FindBin qw($RealBin);
 use lib "$RealBin";
 use Util;
@@ -60,6 +60,7 @@ is(1, is_scalar({TYPE => "DECLARE", DATA => {TYPE => "ENUM" }}));
 
 is(1, scalar_is_reference("string"));
 is(0, scalar_is_reference("uint32"));
+is(0, scalar_is_reference({TYPE => "STRUCT", NAME => "echo_foobar"}));
 
 is("uint8", enum_type_fn({TYPE => "ENUM", PARENT=>{PROPERTIES => {enum8bit => 1}}}));
 is("uint32", enum_type_fn({TYPE => "ENUM", PARENT=>{PROPERTIES => {v1_enum => 1}}}));