summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/pidl/lib/Parse/Pidl/NDR.pm4
-rw-r--r--source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm34
-rwxr-xr-xsource4/pidl/tests/ndr.pl28
-rwxr-xr-xsource4/pidl/tests/samba-ndr.pl34
4 files changed, 82 insertions, 18 deletions
diff --git a/source4/pidl/lib/Parse/Pidl/NDR.pm b/source4/pidl/lib/Parse/Pidl/NDR.pm
index 2ba8461e4a..b76a0f5a38 100644
--- a/source4/pidl/lib/Parse/Pidl/NDR.pm
+++ b/source4/pidl/lib/Parse/Pidl/NDR.pm
@@ -371,7 +371,7 @@ sub ParseElement($)
TYPE => $e->{TYPE},
PROPERTIES => $e->{PROPERTIES},
LEVELS => GetElementLevelTable($e),
- REPRESENTATION_TYPE => $e->{PROPERTIES}->{represent_as},
+ REPRESENTATION_TYPE => ($e->{PROPERTIES}->{represent_as} or $e->{TYPE}),
ALIGN => align_type($e->{TYPE}),
ORIGINAL => $e
};
@@ -388,7 +388,7 @@ sub ParseStruct($$)
my $e = ParseElement($x);
if ($x != $struct->{ELEMENTS}[-1] and
$e->{LEVELS}[0]->{IS_SURROUNDING}) {
- print "$x->{FILE}:$x->{LINE}: error: conformant member not at end of struct\n";
+ fatal($x, "conformant member not at end of struct");
}
push @elements, $e;
}
diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
index d4c4d55c57..6e4d5825d0 100644
--- a/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
+++ b/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
@@ -703,7 +703,7 @@ sub ParseElementPush($$$$$)
return unless $primitives or ($deferred and ContainsDeferred($e, $e->{LEVELS}[0]));
# Representation type is different from transmit_as
- if ($e->{REPRESENTATION_TYPE}) {
+ if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) {
pidl "{";
indent;
my $transmit_name = "_transmit_$e->{NAME}";
@@ -724,7 +724,7 @@ sub ParseElementPush($$$$$)
end_flags($e);
- if ($e->{REPRESENTATION_TYPE}) {
+ if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) {
deindent;
pidl "}";
}
@@ -760,7 +760,7 @@ sub ParseElementPrint($$$)
return if (has_property($e, "noprint"));
- if ($e->{REPRESENTATION_TYPE}) {
+ if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) {
pidl "ndr_print_$e->{REPRESENTATION_TYPE}(ndr, \"$e->{NAME}\", $var_name);";
return;
}
@@ -1110,7 +1110,7 @@ sub ParseElementPull($$$$$)
return unless $primitives or ($deferred and ContainsDeferred($e, $e->{LEVELS}[0]));
- if ($e->{REPRESENTATION_TYPE}) {
+ if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) {
pidl "{";
indent;
$represent_name = $var_name;
@@ -1128,7 +1128,7 @@ sub ParseElementPull($$$$$)
end_flags($e);
# Representation type is different from transmit_as
- if ($e->{REPRESENTATION_TYPE}) {
+ if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) {
pidl "NDR_CHECK(ndr_$e->{TYPE}_to_$e->{REPRESENTATION_TYPE}($transmit_name, ".get_pointer_to($represent_name)."));";
deindent;
pidl "}";
@@ -2488,8 +2488,28 @@ sub NeededElement($$$)
{
my ($e, $dir, $needed) = @_;
- return if (defined($needed->{"$dir\_$e->{TYPE}"}));
- $needed->{"$dir\_$e->{TYPE}"} = 1;
+ return if ($e->{TYPE} eq "EMPTY");
+
+ my @fn = ();
+ if ($dir eq "print") {
+ push(@fn, "print_$e->{REPRESENTATION_TYPE}");
+ } elsif ($dir eq "pull") {
+ push (@fn, "pull_$e->{TYPE}");
+ push (@fn, "ndr_$e->{TYPE}_to_$e->{REPRESENTATION_TYPE}")
+ if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE});
+ } elsif ($dir eq "push") {
+ push (@fn, "push_$e->{TYPE}");
+ push (@fn, "ndr_$e->{REPRESENTATION_TYPE}_to_$e->{TYPE}")
+ if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE});
+ } else {
+ die("invalid direction `$dir'");
+ }
+
+ foreach (@fn) {
+ unless (defined($needed->{$_})) {
+ $needed->{$_} = 1;
+ }
+ }
}
sub NeededFunction($$)
diff --git a/source4/pidl/tests/ndr.pl b/source4/pidl/tests/ndr.pl
index da22949c6d..baf06b1eae 100755
--- a/source4/pidl/tests/ndr.pl
+++ b/source4/pidl/tests/ndr.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;
@@ -189,3 +189,29 @@ is_deeply(GetElementLevelTable($e), [
'CONVERT_TO' => undef
}
]);
+
+# representation_type
+$e = {
+ 'FILE' => 'foo.idl',
+ 'NAME' => 'v',
+ 'PROPERTIES' => { represent_as => "bar" },
+ 'POINTERS' => 0,
+ 'TYPE' => 'uint8',
+ 'PARENT' => { TYPE => 'STRUCT' },
+ 'LINE' => 42 };
+
+$ne = ParseElement($e);
+is($ne->{REPRESENTATION_TYPE}, "bar");
+
+# representation_type
+$e = {
+ 'FILE' => 'foo.idl',
+ 'NAME' => 'v',
+ 'PROPERTIES' => { },
+ 'POINTERS' => 0,
+ 'TYPE' => 'uint8',
+ 'PARENT' => { TYPE => 'STRUCT' },
+ 'LINE' => 42 };
+
+$ne = ParseElement($e);
+is($ne->{REPRESENTATION_TYPE}, "uint8");
diff --git a/source4/pidl/tests/samba-ndr.pl b/source4/pidl/tests/samba-ndr.pl
index f64a8c4093..1f859db788 100755
--- a/source4/pidl/tests/samba-ndr.pl
+++ b/source4/pidl/tests/samba-ndr.pl
@@ -4,7 +4,7 @@
use strict;
use warnings;
-use Test::More tests => 29;
+use Test::More tests => 31;
use FindBin qw($RealBin);
use lib "$RealBin";
use Util;
@@ -176,27 +176,27 @@ EnvSubstituteValue($env, $fn);
is_deeply($env, { foo => 0, this => "r" });
my $needed = {};
-NeededElement({ TYPE => "foo" }, "pull", $needed);
+NeededElement({ TYPE => "foo", REPRESENTATION_TYPE => "foo" }, "pull", $needed);
is_deeply($needed, { pull_foo => 1 });
# old settings should be kept
$needed = { pull_foo => 0 };
-NeededElement({ TYPE => "foo" }, "pull", $needed);
+NeededElement({ TYPE => "foo", REPRESENTATION_TYPE => "foo" }, "pull", $needed);
is_deeply($needed, { pull_foo => 0 });
# print/pull/push are independent of each other
$needed = { pull_foo => 0 };
-NeededElement({ TYPE => "foo" }, "print", $needed);
+NeededElement({ TYPE => "foo", REPRESENTATION_TYPE => "foo" }, "print", $needed);
is_deeply($needed, { pull_foo => 0, print_foo => 1 });
$needed = { };
-NeededFunction({ NAME => "foo", ELEMENTS => [ { TYPE => "bar" } ] }, $needed);
+NeededFunction({ NAME => "foo", ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "bar" } ] }, $needed);
is_deeply($needed, { pull_foo => 1, print_foo => 1, push_foo => 1,
pull_bar => 1, print_bar => 1, push_bar => 1});
# push/pull/print are always set for functions
$needed = { pull_foo => 0 };
-NeededFunction({ NAME => "foo", ELEMENTS => [ { TYPE => "bar" } ] }, $needed);
+NeededFunction({ NAME => "foo", ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "bar" } ] }, $needed);
is_deeply($needed, { pull_foo => 1, print_foo => 1, push_foo => 1,
pull_bar => 1, push_bar => 1, print_bar => 1});
@@ -216,7 +216,7 @@ is_deeply($needed, { pull_bla => 1, print_bla => 1, push_bla => 1 });
$needed = {};
NeededTypedef({ PROPERTIES => { public => 1 }, NAME => "bla",
DATA => { TYPE => "STRUCT",
- ELEMENTS => [ { TYPE => "bar" } ] } },
+ ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "bar" } ] } },
$needed);
is_deeply($needed, { pull_bla => 1, print_bla => 1, push_bla => 1,
pull_bar => 1, print_bar => 1, push_bar => 1});
@@ -224,7 +224,25 @@ is_deeply($needed, { pull_bla => 1, print_bla => 1, push_bla => 1,
$needed = {};
NeededTypedef({ PROPERTIES => { gensize => 1}, NAME => "bla",
DATA => { TYPE => "STRUCT",
- ELEMENTS => [ { TYPE => "bar" } ] } },
+ ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "bar" } ] } },
$needed);
is_deeply($needed, { ndr_size_bla => 1 });
+# make sure types for elements are set too
+$needed = { pull_bla => 1 };
+NeededTypedef({ NAME => "bla",
+ DATA => { TYPE => "STRUCT",
+ ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "bar" } ] } },
+ $needed);
+is_deeply($needed, { pull_bla => 1, pull_bar => 1 });
+
+$needed = {};
+NeededTypedef({ PROPERTIES => { public => 1},
+ NAME => "bla",
+ DATA => { TYPE => "STRUCT",
+ ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "rep" } ] } },
+ $needed);
+is_deeply($needed, { pull_bla => 1, push_bla => 1, print_bla => 1, print_rep => 1,
+ pull_bar => 1, push_bar => 1,
+ ndr_bar_to_rep => 1, ndr_rep_to_bar => 1});
+