diff options
-rw-r--r-- | source4/pidl/lib/Parse/Pidl/NDR.pm | 4 | ||||
-rw-r--r-- | source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm | 34 | ||||
-rwxr-xr-x | source4/pidl/tests/ndr.pl | 28 | ||||
-rwxr-xr-x | source4/pidl/tests/samba-ndr.pl | 34 |
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}); + |