[SCM] Samba Shared Repository - branch v4-0-test updated - release-4-0-0alpha2-605-g8ebf16c

Stefan Metzmacher metze at samba.org
Sat Feb 2 10:05:37 GMT 2008


The branch, v4-0-test has been updated
       via  8ebf16c0741085fa769fcc2929f275ab49b1ea5d (commit)
       via  6fcf2456d0e81898b5779ef1650f38b4c5363a80 (commit)
       via  0569139ca2960ec5478829c3e66f7ff69bdb55cd (commit)
       via  13afc89a87716063180723f0e9cb4f76daca837e (commit)
       via  29c104944bcad30c6a2a3fa70d527bf0ee8969de (commit)
       via  3369015f5d8c425e1a9f9d861471028f03f163bb (commit)
      from  3c191981436ab3f7dd166a87875ffbac127fbdf5 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v4-0-test


- Log -----------------------------------------------------------------
commit 8ebf16c0741085fa769fcc2929f275ab49b1ea5d
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jan 31 15:04:22 2008 +0100

    Works!!!...pidl/Samba4::NDR::Parser: fix support for embedded "ref" pointers
    
    The memory allocation of embedded "ref" pointers needs to be the
    same as for all other embedded pointers.
    
    metze

commit 6fcf2456d0e81898b5779ef1650f38b4c5363a80
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Feb 1 23:09:37 2008 +0100

    WORKS!!!...pidl/NDR: fix handling of multilevel pointers in function elements
    
    The 2nd or higher level of wire pointers needs to be marked as deferred.
    
    metze

commit 0569139ca2960ec5478829c3e66f7ff69bdb55cd
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Feb 1 10:30:47 2008 +0100

    LOOKS OK... pidl: get the pointer types correct when an element has multiple pointers
    
    Only the first level gets the pointer type from the
    pointer property, the others get them from
    the pointer_default() interface property
    
    see http://msdn2.microsoft.com/en-us/library/aa378984(VS.85).aspx
    (Here they talk about the rightmost pointer, but testing shows
    they mean the leftmost pointer.)
    
    metze

commit 13afc89a87716063180723f0e9cb4f76daca837e
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jan 31 14:57:35 2008 +0100

    CHECKED... pidl/Samba4::NDR::Parser: correctly get the name of an array element
    
    When we have "*r->out.ous"
    (char ***ous, a pointer to a pointer to an array).
    we need to use "(*r->out.ous)[3]" to access the 3rd
    element of the array "*r->out.ous[3]" was generated before,
    but that's the same as "*(r->out.ous[3])".
    
    metze

commit 29c104944bcad30c6a2a3fa70d527bf0ee8969de
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Feb 1 09:54:25 2008 +0100

    CHECKED... TODO:MSG pidl/Samba4::NDR::Parser: fix ...
    
    metze

commit 3369015f5d8c425e1a9f9d861471028f03f163bb
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Feb 1 09:49:54 2008 +0100

    CHECKED... pidl/Samba4::NDR::Parser: move logic for extra get_pointer_of() into a function
    
    metze

-----------------------------------------------------------------------

Summary of changes:
 source/pidl/lib/Parse/Pidl/CUtil.pm             |   15 +-
 source/pidl/lib/Parse/Pidl/NDR.pm               |   37 ++-
 source/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm |   96 +++++---
 source/pidl/tests/ndr.pl                        |  289 ++++++++++++++++++++++-
 4 files changed, 379 insertions(+), 58 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/pidl/lib/Parse/Pidl/CUtil.pm b/source/pidl/lib/Parse/Pidl/CUtil.pm
index bd7b168..9deb6ee 100644
--- a/source/pidl/lib/Parse/Pidl/CUtil.pm
+++ b/source/pidl/lib/Parse/Pidl/CUtil.pm
@@ -6,7 +6,7 @@ package Parse::Pidl::CUtil;
 
 require Exporter;
 @ISA = qw(Exporter);
- at EXPORT = qw(get_pointer_to get_value_of);
+ at EXPORT = qw(get_pointer_to get_value_of get_array_element);
 use vars qw($VERSION);
 $VERSION = '0.01';
 
@@ -36,4 +36,17 @@ sub get_value_of($)
 	}
 }
 
+sub get_array_element($$)
+{
+	my ($var_name, $idx) = @_;
+
+	if ($var_name =~ /^\*.*$/) {
+		$var_name = "($var_name)";
+	} elsif ($var_name =~ /^\&.*$/) {
+		$var_name = "($var_name)";
+	}
+
+	return "$var_name"."[$idx]";
+}
+
 1;
diff --git a/source/pidl/lib/Parse/Pidl/NDR.pm b/source/pidl/lib/Parse/Pidl/NDR.pm
index 98e8f18..003eaf0 100644
--- a/source/pidl/lib/Parse/Pidl/NDR.pm
+++ b/source/pidl/lib/Parse/Pidl/NDR.pm
@@ -72,9 +72,9 @@ my $scalar_alignment = {
 	'ipv4address' => 4
 };
 
-sub GetElementLevelTable($)
+sub GetElementLevelTable($$)
 {
-	my $e = shift;
+	my ($e, $pointer_default) = @_;
 
 	my $order = [];
 	my $is_deferred = 0;
@@ -157,32 +157,45 @@ sub GetElementLevelTable($)
 
 	# Next, all the pointers
 	foreach my $i (1..$e->{POINTERS}) {
-		my $pt = pointer_type($e);
-
 		my $level = "EMBEDDED";
 		# Top level "ref" pointers do not have a referrent identifier
-		$level = "TOP" if ( defined($pt) 
-				and $i == 1
-				and $e->{PARENT}->{TYPE} eq "FUNCTION");
+		$level = "TOP" if ($i == 1 and $e->{PARENT}->{TYPE} eq "FUNCTION");
+
+		my $pt;
+		#
+		# Only the first level gets the pointer type from the
+		# pointer property, the others get them from
+		# the pointer_default() interface property
+		#
+		# see http://msdn2.microsoft.com/en-us/library/aa378984(VS.85).aspx
+		# (Here they talk about the rightmost pointer, but testing shows
+		#  they mean the leftmost pointer.)
+		#
+		# --metze
+		#
+		$pt = pointer_type($e);
+		if ($i > 1) {
+			$is_deferred = 1 if ($pt ne "ref" and $e->{PARENT}->{TYPE} eq "FUNCTION");
+			$pt = $pointer_default;
+		}
 
 		push (@$order, { 
 			TYPE => "POINTER",
-			# for now, there can only be one pointer type per element
-			POINTER_TYPE => pointer_type($e),
+			POINTER_TYPE => $pt,
 			POINTER_INDEX => $pointer_idx,
 			IS_DEFERRED => "$is_deferred",
 			LEVEL => $level
 		});
 
 		warning($e, "top-level \[out\] pointer `$e->{NAME}' is not a \[ref\] pointer") 
-			if ($i == 1 and pointer_type($e) ne "ref" and 
+			if ($i == 1 and $pt ne "ref" and
 				$e->{PARENT}->{TYPE} eq "FUNCTION" and 
 				not has_property($e, "in"));
 
 		$pointer_idx++;
 		
 		# everything that follows will be deferred
-		$is_deferred = 1 if ($e->{PARENT}->{TYPE} ne "FUNCTION");
+		$is_deferred = 1 if ($level ne "TOP");
 
 		my $array_size = shift @size_is;
 		my $array_length;
@@ -391,7 +404,7 @@ sub ParseElement($$)
 		NAME => $e->{NAME},
 		TYPE => $e->{TYPE},
 		PROPERTIES => $e->{PROPERTIES},
-		LEVELS => GetElementLevelTable($e),
+		LEVELS => GetElementLevelTable($e, $pointer_default),
 		REPRESENTATION_TYPE => ($e->{PROPERTIES}->{represent_as} or $e->{TYPE}),
 		ALIGN => align_type($e->{TYPE}),
 		ORIGINAL => $e
diff --git a/source/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/source/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
index 8326ce5..6e6d227 100644
--- a/source/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
+++ b/source/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
@@ -14,7 +14,7 @@ require Exporter;
 use strict;
 use Parse::Pidl::Typelist qw(hasType getType mapTypeName typeHasBody);
 use Parse::Pidl::Util qw(has_property ParseExpr ParseExprExt print_uuid);
-use Parse::Pidl::CUtil qw(get_pointer_to get_value_of);
+use Parse::Pidl::CUtil qw(get_pointer_to get_value_of get_array_element);
 use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred is_charset_array);
 use Parse::Pidl::Samba4 qw(is_intree choose_header);
 use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv);
@@ -42,19 +42,21 @@ sub append_prefix($$)
 {
 	my ($e, $var_name) = @_;
 	my $pointers = 0;
+	my $arrays = 0;
 
 	foreach my $l (@{$e->{LEVELS}}) {
 		if ($l->{TYPE} eq "POINTER") {
 			$pointers++;
 		} elsif ($l->{TYPE} eq "ARRAY") {
+			$arrays++;
 			if (($pointers == 0) and 
 			    (not $l->{IS_FIXED}) and
 			    (not $l->{IS_INLINE})) {
-				return get_value_of($var_name); 
+				return get_value_of($var_name);
 			}
 		} elsif ($l->{TYPE} eq "DATA") {
 			if (Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) {
-				return get_value_of($var_name) unless ($pointers);
+				return get_value_of($var_name) unless ($pointers or $arrays);
 			}
 		}
 	}
@@ -582,7 +584,7 @@ sub ParseElementPushLevel
 		my $length = ParseExpr($l->{LENGTH_IS}, $env, $e->{ORIGINAL});
 		my $counter = "cntr_$e->{NAME}_$l->{LEVEL_INDEX}";
 
-		$var_name = $var_name . "[$counter]";
+		$var_name = get_array_element($var_name, $counter);
 
 		if (($primitives and not $l->{IS_DEFERRED}) or ($deferred and $l->{IS_DEFERRED})) {
 			$self->pidl("for ($counter = 0; $counter < $length; $counter++) {");
@@ -669,23 +671,48 @@ sub ParsePtrPush($$$$)
 	}
 }
 
+sub need_pointer_to($$$)
+{
+	my ($e, $l, $scalar_only) = @_;
+
+	my $t;
+	if (ref($l->{DATA_TYPE})) {
+		$t = "$l->{DATA_TYPE}->{TYPE}_$l->{DATA_TYPE}->{NAME}";
+	} else {
+		$t = $l->{DATA_TYPE};
+	}
+
+	if (not Parse::Pidl::Typelist::is_scalar($t)) {
+		return 1 if $scalar_only;
+	}
+
+	my $arrays = 0;
+
+	foreach my $tl (@{$e->{LEVELS}}) {
+		last if $l == $tl;
+		if ($tl->{TYPE} eq "ARRAY") {
+			$arrays++;
+		}
+	}
+
+	if (Parse::Pidl::Typelist::scalar_is_reference($t)) {
+		return 1 unless $arrays;
+	}
+
+	return 0;
+}
+
 sub ParseDataPrint($$$$)
 {
 	my ($self, $e, $l, $var_name) = @_;
 	
-	if (not ref($l->{DATA_TYPE}) or 
-		defined($l->{DATA_TYPE}->{NAME})) {
-		my $t;
-		if (ref($l->{DATA_TYPE})) {
-			$t = "$l->{DATA_TYPE}->{TYPE}_$l->{DATA_TYPE}->{NAME}";
-		} else {
-			$t = $l->{DATA_TYPE};
-		}
-		if (not Parse::Pidl::Typelist::is_scalar($t) or 
-			Parse::Pidl::Typelist::scalar_is_reference($t)) {
+	if (not ref($l->{DATA_TYPE}) or defined($l->{DATA_TYPE}->{NAME})) {
+
+		if (need_pointer_to($e, $l, 1)) {
 			$var_name = get_pointer_to($var_name);
 		}
-		$self->pidl("ndr_print_$t(ndr, \"$e->{NAME}\", $var_name);");
+
+		$self->pidl(TypeFunctionName("ndr_print", $l->{DATA_TYPE})."(ndr, \"$e->{NAME}\", $var_name);");
 	} else {
 		$self->ParseTypePrint($l->{DATA_TYPE}, $var_name);
 	}
@@ -752,7 +779,7 @@ sub ParseElementPrint($$$$)
 				$self->pidl("if (idx_$l->{LEVEL_INDEX}) {");
 				$self->indent;
 
-				$var_name = $var_name . "[$counter]";
+				$var_name = get_array_element($var_name, $counter);
 			}
 		} elsif ($l->{TYPE} eq "DATA") {
 			$self->ParseDataPrint($e, $l, $var_name);
@@ -815,12 +842,11 @@ sub ParseDataPull($$$$$$$)
 {
 	my ($self,$e,$l,$ndr,$var_name,$primitives,$deferred) = @_;
 
-	if (not ref($l->{DATA_TYPE}) or 
-		defined($l->{DATA_TYPE}->{NAME})) {
+	if (not ref($l->{DATA_TYPE}) or defined($l->{DATA_TYPE}->{NAME})) {
 
 		my $ndr_flags = CalcNdrFlags($l, $primitives, $deferred);
 
-		if (Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) {
+		if (need_pointer_to($e, $l, 0)) {
 			$var_name = get_pointer_to($var_name);
 		}
 
@@ -845,21 +871,15 @@ sub ParseDataPush($$$$$$$)
 	my ($self,$e,$l,$ndr,$var_name,$primitives,$deferred) = @_;
 
 	if (not ref($l->{DATA_TYPE}) or defined($l->{DATA_TYPE}->{NAME})) {
-		my $t;
-		if (ref($l->{DATA_TYPE}) eq "HASH") {
-			$t = "$l->{DATA_TYPE}->{TYPE}_$l->{DATA_TYPE}->{NAME}";
-		} else {
-			$t = $l->{DATA_TYPE};
-		}
-				
+
+		my $ndr_flags = CalcNdrFlags($l, $primitives, $deferred);
+
 		# strings are passed by value rather than reference
-		if (not Parse::Pidl::Typelist::is_scalar($t) or 
-			Parse::Pidl::Typelist::scalar_is_reference($t)) {
+		if (need_pointer_to($e, $l, 1)) {
 			$var_name = get_pointer_to($var_name);
 		}
 
-		my $ndr_flags = CalcNdrFlags($l, $primitives, $deferred);
-		$self->pidl("NDR_CHECK(ndr_push_$t($ndr, $ndr_flags, $var_name));");
+		$self->pidl("NDR_CHECK(".TypeFunctionName("ndr_push", $l->{DATA_TYPE})."($ndr, $ndr_flags, $var_name));");
 	} else {
 		$self->ParseTypePush($l->{DATA_TYPE}, $var_name, $primitives, $deferred);
 	}
@@ -909,7 +929,7 @@ sub ParseMemCtxPullFlags($$$$)
 					($nl->{DATA_TYPE} eq "string"));
 		if ($next_is_array or $next_is_string) {
 			return undef;
-		} else {
+		} elsif ($l->{LEVEL} eq "TOP") {
 			$mem_flags = "LIBNDR_FLAG_REF_ALLOC";
 		}
 	}
@@ -1028,7 +1048,7 @@ sub ParseElementPullLevel
 		my $counter = "cntr_$e->{NAME}_$l->{LEVEL_INDEX}";
 		my $array_name = $var_name;
 
-		$var_name = $var_name . "[$counter]";
+		$var_name = get_array_element($var_name, $counter);
 
 		$self->ParseMemCtxPullStart($e, $l, $array_name);
 
@@ -1109,10 +1129,7 @@ sub ParsePtrPull($$$$$)
 	my $next_is_string = (($nl->{TYPE} eq "DATA") and 
 						 ($nl->{DATA_TYPE} eq "string"));
 
-	if ($l->{POINTER_TYPE} eq "ref") {
-		if ($l->{LEVEL} eq "EMBEDDED") {
-			$self->pidl("NDR_CHECK(ndr_pull_ref_ptr($ndr, &_ptr_$e->{NAME}));");
-		}
+	if ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "TOP") {
 
 		if (!$next_is_array and !$next_is_string) {
 			$self->pidl("if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {");
@@ -1121,16 +1138,19 @@ sub ParsePtrPull($$$$$)
 		}
 		
 		return;
+	} elsif ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "EMBEDDED") {
+		$self->pidl("NDR_CHECK(ndr_pull_ref_ptr($ndr, &_ptr_$e->{NAME}));");
 	} elsif (($l->{POINTER_TYPE} eq "unique") or 
 		 ($l->{POINTER_TYPE} eq "relative") or
 		 ($l->{POINTER_TYPE} eq "full")) {
 		$self->pidl("NDR_CHECK(ndr_pull_generic_ptr($ndr, &_ptr_$e->{NAME}));");
-		$self->pidl("if (_ptr_$e->{NAME}) {");
-		$self->indent;
 	} else {
 		die("Unhandled pointer type $l->{POINTER_TYPE}");
 	}
 
+	$self->pidl("if (_ptr_$e->{NAME}) {");
+	$self->indent;
+
 	# Don't do this for arrays, they're allocated at the actual level 
 	# of the array
 	unless ($next_is_array or $next_is_string) { 
diff --git a/source/pidl/tests/ndr.pl b/source/pidl/tests/ndr.pl
index 7fcc7ef..504b7ec 100755
--- a/source/pidl/tests/ndr.pl
+++ b/source/pidl/tests/ndr.pl
@@ -4,7 +4,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 40;
+use Test::More tests => 46;
 use FindBin qw($RealBin);
 use lib "$RealBin";
 use Util;
@@ -22,7 +22,7 @@ my $e = {
 	'PARENT' => { TYPE => 'STRUCT' },
 	'LINE' => 42 };
 
-is_deeply(GetElementLevelTable($e), [
+is_deeply(GetElementLevelTable($e, "unique"), [
 	{
 		'IS_DEFERRED' => 0,
 		'LEVEL_INDEX' => 0,
@@ -33,7 +33,7 @@ is_deeply(GetElementLevelTable($e), [
 	}
 ]);
 
-my $ne = ParseElement($e, undef);
+my $ne = ParseElement($e, "unique");
 is($ne->{ORIGINAL}, $e);
 is($ne->{NAME}, "v");
 is($ne->{ALIGN}, 1);
@@ -60,7 +60,7 @@ $e = {
 	'TYPE' => 'uint8',
 	'LINE' => 42 };
 
-is_deeply(GetElementLevelTable($e), [
+is_deeply(GetElementLevelTable($e, "unique"), [
 	{
 		LEVEL_INDEX => 0,
 		IS_DEFERRED => 0,
@@ -90,7 +90,7 @@ $e = {
 	'PARENT' => { TYPE => 'STRUCT' },
 	'LINE' => 42 };
 
-is_deeply(GetElementLevelTable($e), [
+is_deeply(GetElementLevelTable($e, "unique"), [
 	{
 		LEVEL_INDEX => 0,
 		IS_DEFERRED => 0,
@@ -128,7 +128,7 @@ $e = {
 	'PARENT' => { TYPE => 'STRUCT' },
 	'LINE' => 42 };
 
-is_deeply(GetElementLevelTable($e), [
+is_deeply(GetElementLevelTable($e, "unique"), [
 	{
 		LEVEL_INDEX => 0,
 		IS_DEFERRED => 0,
@@ -147,6 +147,97 @@ is_deeply(GetElementLevelTable($e), [
 	}
 ]);
 
+# Case 3 : ref pointers
+#
+$e = {
+	'FILE' => 'foo.idl',
+	'NAME' => 'v',
+	'PROPERTIES' => {"ref" => 1},
+	'POINTERS' => 3,
+	'TYPE' => 'uint8',
+	'PARENT' => { TYPE => 'STRUCT' },
+	'LINE' => 42 };
+
+is_deeply(GetElementLevelTable($e, "unique"), [
+	{
+		LEVEL_INDEX => 0,
+		IS_DEFERRED => 0,
+		TYPE => 'POINTER',
+		POINTER_TYPE => "ref",
+		POINTER_INDEX => 0,
+		LEVEL => 'EMBEDDED'
+	},
+	{
+		LEVEL_INDEX => 1,
+		IS_DEFERRED => 1,
+		TYPE => 'POINTER',
+		POINTER_TYPE => "unique",
+		POINTER_INDEX => 1,
+		LEVEL => 'EMBEDDED'
+	},
+	{
+		LEVEL_INDEX => 2,
+		IS_DEFERRED => 1,
+		TYPE => 'POINTER',
+		POINTER_TYPE => "unique",
+		POINTER_INDEX => 2,
+		LEVEL => 'EMBEDDED'
+	},
+	{
+		'IS_DEFERRED' => 1,
+		'LEVEL_INDEX' => 3,
+		'DATA_TYPE' => 'uint8',
+		'CONTAINS_DEFERRED' => 0,
+		'TYPE' => 'DATA',
+		'IS_SURROUNDING' => 0,
+	}
+]);
+
+# Case 3 : ref pointers
+#
+$e = {
+	'FILE' => 'foo.idl',
+	'NAME' => 'v',
+	'PROPERTIES' => {"ref" => 1},
+	'POINTERS' => 3,
+	'TYPE' => 'uint8',
+	'PARENT' => { TYPE => 'STRUCT' },
+	'LINE' => 42 };
+
+is_deeply(GetElementLevelTable($e, "ref"), [
+	{
+		LEVEL_INDEX => 0,
+		IS_DEFERRED => 0,
+		TYPE => 'POINTER',
+		POINTER_TYPE => "ref",
+		POINTER_INDEX => 0,
+		LEVEL => 'EMBEDDED'
+	},
+	{
+		LEVEL_INDEX => 1,
+		IS_DEFERRED => 1,
+		TYPE => 'POINTER',
+		POINTER_TYPE => "ref",
+		POINTER_INDEX => 1,
+		LEVEL => 'EMBEDDED'
+	},
+	{
+		LEVEL_INDEX => 2,
+		IS_DEFERRED => 1,
+		TYPE => 'POINTER',
+		POINTER_TYPE => "ref",
+		POINTER_INDEX => 2,
+		LEVEL => 'EMBEDDED'
+	},
+	{
+		'IS_DEFERRED' => 1,
+		'LEVEL_INDEX' => 3,
+		'DATA_TYPE' => 'uint8',
+		'CONTAINS_DEFERRED' => 0,
+		'TYPE' => 'DATA',
+		'IS_SURROUNDING' => 0,
+	}
+]);
 
 # Case 4 : top-level ref pointers
 #
@@ -159,7 +250,7 @@ $e = {
 	'PARENT' => { TYPE => 'FUNCTION' },
 	'LINE' => 42 };
 
-is_deeply(GetElementLevelTable($e), [
+is_deeply(GetElementLevelTable($e, "unique"), [
 	{
 		LEVEL_INDEX => 0,
 		IS_DEFERRED => 0,
@@ -178,6 +269,190 @@ is_deeply(GetElementLevelTable($e), [
 	}
 ]);
 
+# Case 4 : top-level ref pointers, triple with pointer_default("unique")
+#
+$e = {
+	'FILE' => 'foo.idl',
+	'NAME' => 'v',
+	'PROPERTIES' => {"ref" => 1},
+	'POINTERS' => 3,
+	'TYPE' => 'uint8',
+	'PARENT' => { TYPE => 'FUNCTION' },
+	'LINE' => 42 };
+


-- 
Samba Shared Repository


More information about the samba-cvs mailing list