From d7a7b7fb0c423c461c24e8157ad926d0cee07da1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 27 Feb 2007 23:47:07 +0000 Subject: r21572: More work towards supporting tagged types. (This used to be commit 4d28396f0928444406334888f4bc345e74a380df) --- source4/pidl/lib/Parse/Pidl/NDR.pm | 16 ++++++++----- source4/pidl/lib/Parse/Pidl/Typelist.pm | 7 ++++++ source4/pidl/tests/ndr.pl | 12 ++++++++-- source4/pidl/tests/ndr_tagtype.pl | 41 ++++++++++++++++++++++++++++++++- source4/pidl/tests/typelist.pl | 14 ++++++++--- 5 files changed, 78 insertions(+), 12 deletions(-) diff --git a/source4/pidl/lib/Parse/Pidl/NDR.pm b/source4/pidl/lib/Parse/Pidl/NDR.pm index 7322856cdd..3e45bca1ad 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); +@EXPORT_OK = qw(GetElementLevelTable ParseElement ValidElement align_type); use strict; use Parse::Pidl qw(warning fatal); @@ -335,7 +335,11 @@ sub find_largest_alignment($) sub align_type($) { sub align_type($); - my $e = shift; + my ($e) = @_; + + if (ref($e) eq "HASH" and $e->{TYPE} eq "SCALAR") { + return $scalar_alignment->{$e->{NAME}}; + } unless (hasType($e)) { # it must be an external type - all we can do is guess @@ -343,16 +347,16 @@ sub align_type($) return 4; } - my $dt = getType($e)->{DATA}; + my $dt = getType($e); - if ($dt->{TYPE} eq "ENUM") { + if ($dt->{TYPE} eq "TYPEDEF") { + return align_type($dt->{DATA}); + } elsif ($dt->{TYPE} eq "ENUM") { return align_type(Parse::Pidl::Typelist::enum_type_fn($dt)); } elsif ($dt->{TYPE} eq "BITMAP") { return align_type(Parse::Pidl::Typelist::bitmap_type_fn($dt)); } elsif (($dt->{TYPE} eq "STRUCT") or ($dt->{TYPE} eq "UNION")) { return find_largest_alignment($dt); - } elsif ($dt->{TYPE} eq "SCALAR") { - return $scalar_alignment->{$dt->{NAME}}; } die("Unknown data type type $dt->{TYPE}"); diff --git a/source4/pidl/lib/Parse/Pidl/Typelist.pm b/source4/pidl/lib/Parse/Pidl/Typelist.pm index 55f8390f65..b25ab62e03 100644 --- a/source4/pidl/lib/Parse/Pidl/Typelist.pm +++ b/source4/pidl/lib/Parse/Pidl/Typelist.pm @@ -98,7 +98,9 @@ sub addType($) sub getType($) { my $t = shift; + return ($t) if (ref($t) eq "HASH" and not defined($t->{NAME})); return undef if not hasType($t); + return $types{$t->{NAME}} if (ref($t) eq "HASH"); return $types{$t}; } @@ -113,6 +115,11 @@ sub typeIs($$) sub hasType($) { my $t = shift; + if (ref($t) eq "HASH") { + return 1 if (defined($types{$t->{NAME}}) and + $types{$t->{NAME}}->{TYPE} eq $t->{TYPE}); + return 0; + } return 1 if defined($types{$t}); return 0; } diff --git a/source4/pidl/tests/ndr.pl b/source4/pidl/tests/ndr.pl index 26fb6c290b..9824d1e815 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 => 12; +use Test::More tests => 17; use FindBin qw($RealBin); use lib "$RealBin"; use Util; use Parse::Pidl::Util qw(MyDumper); -use Parse::Pidl::NDR qw(GetElementLevelTable ParseElement); +use Parse::Pidl::NDR qw(GetElementLevelTable ParseElement align_type); # Case 1 @@ -203,3 +203,11 @@ $e = { $ne = ParseElement($e, undef); is($ne->{REPRESENTATION_TYPE}, "uint8"); + +is(align_type("uint32"), 4); +is(align_type("uint16"), 2); +is(align_type("uint8"), 1); +is(align_type({ TYPE => "STRUCT", "NAME" => "bla", + ELEMENTS => [ { TYPE => "uint16" } ] }), 4); +is(align_type({ TYPE => "STRUCT", "NAME" => "bla", + ELEMENTS => [ { TYPE => "uint8" } ] }), 4); diff --git a/source4/pidl/tests/ndr_tagtype.pl b/source4/pidl/tests/ndr_tagtype.pl index 067fa096b4..efc5b67746 100755 --- a/source4/pidl/tests/ndr_tagtype.pl +++ b/source4/pidl/tests/ndr_tagtype.pl @@ -3,7 +3,7 @@ # (C) 2005 Jelmer Vernooij. Published under the GNU GPL use strict; -use Test::More tests => 1 * 8; +use Test::More tests => 3 * 8; use FindBin qw($RealBin); use lib "$RealBin"; use Util qw(test_samba4_ndr); @@ -25,3 +25,42 @@ test_samba4_ndr('struct-notypedef', '[public] struct bla { uint8 x; }; ', if (!data_blob_equal(&result_blob, &expected_blob)) return 2; '); + +test_samba4_ndr('struct-notypedef-used', '[public] struct bla { uint8 x; }; + [public] void myfn([in] struct bla r); ', +' + struct ndr_push *ndr = ndr_push_init_ctx(NULL); + struct bla r; + uint8_t expected[] = { 0x0D }; + DATA_BLOB expected_blob = { expected, 1 }; + DATA_BLOB result_blob; + r.x = 13; + + if (NT_STATUS_IS_ERR(ndr_push_myfn(ndr, NDR_IN, &r))) + return 1; + + result_blob = ndr_push_blob(ndr); + + if (!data_blob_equal(&result_blob, &expected_blob)) + return 2; +'); + + +test_samba4_ndr('struct-notypedef-embedded', 'struct bla { uint8 x; }; + [public] struct myfn { struct bla r; }; ', +' + struct ndr_push *ndr = ndr_push_init_ctx(NULL); + struct bla r; + uint8_t expected[] = { 0x0D }; + DATA_BLOB expected_blob = { expected, 1 }; + DATA_BLOB result_blob; + r.x = 13; + + if (NT_STATUS_IS_ERR(ndr_push_myfn(ndr, NDR_IN, &r))) + return 1; + + result_blob = ndr_push_blob(ndr); + + if (!data_blob_equal(&result_blob, &expected_blob)) + return 2; +'); diff --git a/source4/pidl/tests/typelist.pl b/source4/pidl/tests/typelist.pl index 5c1a7ddd21..d84fe0592c 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 => 33; +use Test::More tests => 38; use FindBin qw($RealBin); use lib "$RealBin"; use Util; @@ -22,15 +22,23 @@ is("uint32_t", mapScalarType("uint32")); is("void", mapScalarType("void")); is("uint64_t", mapScalarType("hyper")); -my $x = { TYPE => "ENUM", NAME => "foo" }; +my $x = { TYPE => "ENUM", NAME => "foo", EXTRADATA => 1 }; addType($x); -is($x, getType("foo")); +is_deeply($x, getType("foo")); is(undef, getType("bloebla")); +is_deeply(getType({ TYPE => "STRUCT" }), { TYPE => "STRUCT" }); +is_deeply(getType({ TYPE => "ENUM", NAME => "foo" }), $x); +is_deeply(getType("uint16"), { + NAME => "uint16", + TYPE => "TYPEDEF", + DATA => { NAME => "uint16", TYPE => "SCALAR" }}); is(0, typeIs("someUnknownType", "ENUM")); is(1, hasType("foo")); is(0, hasType("nonexistant")); +is(0, hasType({TYPE => "ENUM", NAME => "someUnknownType"})); +is(1, hasType({TYPE => "ENUM", NAME => "foo"})); is(1, is_scalar("uint32")); is(0, is_scalar("nonexistant")); -- cgit