summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/pidl/lib/Parse/Pidl/NDR.pm16
-rw-r--r--source4/pidl/lib/Parse/Pidl/Typelist.pm7
-rwxr-xr-xsource4/pidl/tests/ndr.pl12
-rwxr-xr-xsource4/pidl/tests/ndr_tagtype.pl41
-rwxr-xr-xsource4/pidl/tests/typelist.pl14
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"));