From 5ba8169109253c96f71e0e039b1c0b7a1056eab0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 28 Feb 2007 13:25:53 +0000 Subject: [PATCH] r21584: Support for tagged types has landed! It's now possible to use "struct foo" without a typedef in IDL files. echo_info4 is the first type that's been converted. (This used to be commit 3ac68e858df9b53cf5e0a84741916214a53b3121) --- source4/librpc/idl/echo.idl | 8 ++--- source4/pidl/README | 2 +- source4/pidl/lib/Parse/Pidl/NDR.pm | 3 +- source4/pidl/lib/Parse/Pidl/Samba4/EJS.pm | 46 +++++++++++++--------------- source4/pidl/lib/Parse/Pidl/Samba4/Header.pm | 22 ++++++++----- source4/pidl/tests/header.pl | 8 ++++- source4/pidl/tests/ndr.pl | 7 +++-- source4/pidl/tests/typelist.pl | 3 +- 8 files changed, 56 insertions(+), 43 deletions(-) diff --git a/source4/librpc/idl/echo.idl b/source4/librpc/idl/echo.idl index fa030be761c..5ea37f1ac19 100644 --- a/source4/librpc/idl/echo.idl +++ b/source4/librpc/idl/echo.idl @@ -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; diff --git a/source4/pidl/README b/source4/pidl/README index 88569938163..5bf7752da97 100644 --- a/source4/pidl/README +++ b/source4/pidl/README @@ -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 diff --git a/source4/pidl/lib/Parse/Pidl/NDR.pm b/source4/pidl/lib/Parse/Pidl/NDR.pm index 998b19aabf1..f05e3120c76 100644 --- a/source4/pidl/lib/Parse/Pidl/NDR.pm +++ b/source4/pidl/lib/Parse/Pidl/NDR.pm @@ -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); } diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/EJS.pm b/source4/pidl/lib/Parse/Pidl/Samba4/EJS.pm index c254bfad38e..054074297bc 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/EJS.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/EJS.pm @@ -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;"; diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm index 11ecc170011..2eddf22b059 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm @@ -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") { diff --git a/source4/pidl/tests/header.pl b/source4/pidl/tests/header.pl index 3dae33ae6c5..7092eb0d148 100755 --- a/source4/pidl/tests/header.pl +++ b/source4/pidl/tests/header.pl @@ -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"); diff --git a/source4/pidl/tests/ndr.pl b/source4/pidl/tests/ndr.pl index 17003d59c46..8245f768e84 100755 --- a/source4/pidl/tests/ndr.pl +++ b/source4/pidl/tests/ndr.pl @@ -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" }); diff --git a/source4/pidl/tests/typelist.pl b/source4/pidl/tests/typelist.pl index 376bd208f09..c5c409a5259 100755 --- a/source4/pidl/tests/typelist.pl +++ b/source4/pidl/tests/typelist.pl @@ -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}}})); -- 2.11.4.GIT