From be9af1a4e8d474a544840f657b1be0c302986417 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 5 Oct 2005 22:18:59 +0000 Subject: r10742: Support multi-level pointers + ref pointer fixes (This used to be commit 258b762dc62b257f99d1d859c5a3d850aba3e9fa) --- source4/pidl/lib/Parse/Pidl/NDR.pm | 4 +++ source4/pidl/lib/Parse/Pidl/Samba3/Client.pm | 34 +++++++++++++++--- source4/pidl/lib/Parse/Pidl/Samba3/Header.pm | 4 +-- source4/pidl/lib/Parse/Pidl/Samba3/Parser.pm | 54 ++++++++++++++++++---------- 4 files changed, 71 insertions(+), 25 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/NDR.pm b/source4/pidl/lib/Parse/Pidl/NDR.pm index 6bb92a3b50..64190e87b8 100644 --- a/source4/pidl/lib/Parse/Pidl/NDR.pm +++ b/source4/pidl/lib/Parse/Pidl/NDR.pm @@ -80,6 +80,7 @@ sub GetElementLevelTable($) my @bracket_array = (); my @length_is = (); my @size_is = (); + my $pointer_idx = 0; if (has_property($e, "size_is")) { @size_is = split /,/, has_property($e, "size_is"); @@ -153,9 +154,12 @@ sub GetElementLevelTable($) TYPE => "POINTER", # for now, there can only be one pointer type per element POINTER_TYPE => pointer_type($e), + POINTER_INDEX => $pointer_idx, IS_DEFERRED => "$is_deferred", LEVEL => $level }); + + $pointer_idx++; # everything that follows will be deferred $is_deferred = 1 if ($e->{PARENT}->{TYPE} ne "FUNCTION"); diff --git a/source4/pidl/lib/Parse/Pidl/Samba3/Client.pm b/source4/pidl/lib/Parse/Pidl/Samba3/Client.pm index b48a1b519f..164f53d06b 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba3/Client.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba3/Client.pm @@ -20,6 +20,28 @@ sub indent() { $tabs.="\t"; } sub deindent() { $tabs = substr($tabs, 1); } sub pidl($) { $res .= $tabs.(shift)."\n"; } sub fatal($$) { my ($e,$s) = @_; die("$e->{FILE}:$e->{LINE}: $s\n"); } +sub warning($$) { my ($e,$s) = @_; warn("$e->{FILE}:$e->{LINE}: $s\n"); } + +sub CopyLevel($$$$) +{ + sub CopyLevel($$$$); + my ($e,$l,$argument,$member) = @_; + + if ($l->{TYPE} eq "DATA") { + pidl "*$argument = $member;"; + } elsif ($l->{TYPE} eq "POINTER") { + pidl "if (r.ptr$l->{POINTER_INDEX}_$e->{NAME}) {"; + indent; + pidl "*$argument = talloc_size(mem_ctx, sizeof(void *));"; + CopyLevel($e,GetNextLevel($e,$l),"*$argument", $member); + deindent; + pidl "}"; + } elsif ($l->{TYPE} eq "SWITCH") { + CopyLevel($e,GetNextLevel($e,$l),$argument,$member); + } elsif ($l->{TYPE} eq "ARRAY") { + pidl "*$argument = $member;"; + } +} sub ParseFunction($$) { @@ -59,10 +81,14 @@ sub ParseFunction($$) pidl "\tNT_STATUS_UNSUCCESSFUL);"; pidl ""; pidl "/* Return variables */"; - foreach (@{$fn->{ELEMENTS}}) { - next unless (grep(/out/, @{$_->{DIRECTION}})); - - pidl "*$_->{NAME} = r.$_->{NAME};"; + foreach my $e (@{$fn->{ELEMENTS}}) { + next unless (grep(/out/, @{$e->{DIRECTION}})); + + if ($e->{LEVELS}[0]->{TYPE} ne "POINTER") { + warning($e->{ORIGINAL}, "First element not a pointer for [out] argument"); + next; + } + CopyLevel($e, $e->{LEVELS}[1], $e->{NAME}, "r.$e->{NAME}"); } pidl""; diff --git a/source4/pidl/lib/Parse/Pidl/Samba3/Header.pm b/source4/pidl/lib/Parse/Pidl/Samba3/Header.pm index 4579ae2ec0..1bcaa5c672 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba3/Header.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba3/Header.pm @@ -29,7 +29,7 @@ sub ParseElement($) foreach my $l (@{$e->{LEVELS}}) { if ($l->{TYPE} eq "POINTER") { return if ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "top"); - pidl "\tuint32 ptr_$e->{NAME};"; + pidl "\tuint32 ptr$l->{POINTER_INDEX}_$e->{NAME};"; } elsif ($l->{TYPE} eq "SWITCH") { pidl "\tuint32 level_$e->{NAME};"; } elsif ($l->{TYPE} eq "DATA") { @@ -120,7 +120,7 @@ sub ParseUnion($$$) $extra->{"length"} = $extra->{"offset"} = 1; } } elsif ($l->{TYPE} eq "POINTER") { - $extra->{"ptr"} = 1; + $extra->{"ptr$l->{POINTER_INDEX}"} = 1; } elsif ($l->{TYPE} eq "SWITCH") { $extra->{"level"} = 1; } diff --git a/source4/pidl/lib/Parse/Pidl/Samba3/Parser.pm b/source4/pidl/lib/Parse/Pidl/Samba3/Parser.pm index ac7fde69a6..7cd1255a40 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba3/Parser.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba3/Parser.pm @@ -158,14 +158,16 @@ sub ParseElementLevelPtr($$$$$$$) my ($e,$l,$nl,$env,$varname,$what,$align) = @_; if ($what == PRIMITIVES) { - if ($l->{POINTER_TYPE} eq "ref" and - $l->{LEVEL} eq "TOP") { - pidl "if (!" . ParseExpr("ptr_$e->{NAME}", $env) . ")"; + if (($l->{POINTER_TYPE} eq "ref") and ($l->{LEVEL} eq "EMBEDDED")) { + # Ref pointers always have to be non-NULL + pidl "if (MARSHALLING(ps) && !" . ParseExpr("ptr$l->{POINTER_INDEX}_$e->{NAME}", $env) . ")"; pidl "\treturn False;"; pidl ""; - } else { + } + + unless ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "TOP") { Align($align, 4); - pidl "if (!prs_uint32(\"ptr_$e->{NAME}\", ps, depth, &" . ParseExpr("ptr_$e->{NAME}", $env) . "))"; + pidl "if (!prs_uint32(\"ptr$l->{POINTER_INDEX}_$e->{NAME}\", ps, depth, &" . ParseExpr("ptr$l->{POINTER_INDEX}_$e->{NAME}", $env) . "))"; pidl "\treturn False;"; pidl ""; } @@ -177,12 +179,16 @@ sub ParseElementLevelPtr($$$$$$$) } if ($what == DEFERRED) { - pidl "if (" . ParseExpr("ptr_$e->{NAME}", $env) . ") {"; - indent; + if ($l->{POINTER_TYPE} ne "ref") { + pidl "if (" . ParseExpr("ptr$l->{POINTER_INDEX}_$e->{NAME}", $env) . ") {"; + indent; + } ParseElementLevel($e,$nl,$env,$varname,PRIMITIVES,$align); ParseElementLevel($e,$nl,$env,$varname,DEFERRED,$align); - deindent; - pidl "}"; + if ($l->{POINTER_TYPE} ne "ref") { + deindent; + pidl "}"; + } $$align = 0; } } @@ -221,14 +227,24 @@ sub InitLevel($$$$) my ($e,$l,$varname,$env) = @_; if ($l->{TYPE} eq "POINTER") { - pidl "if ($varname) {"; - indent; - pidl ParseExpr("ptr_$e->{NAME}", $env) . " = 1;"; + if ($l->{POINTER_TYPE} eq "ref") { + pidl "if (!$varname)"; + pidl "\treturn False;"; + pidl ""; + } else { + pidl "if ($varname) {"; + indent; + } + + pidl ParseExpr("ptr$l->{POINTER_INDEX}_$e->{NAME}", $env) . " = 1;"; InitLevel($e, GetNextLevel($e,$l), "*$varname", $env); - deindent; - pidl "} else {"; - pidl "\t" . ParseExpr("ptr_$e->{NAME}", $env) . " = 0;"; - pidl "}"; + + if ($l->{POINTER_TYPE} ne "ref") { + deindent; + pidl "} else {"; + pidl "\t" . ParseExpr("ptr$l->{POINTER_INDEX}_$e->{NAME}", $env) . " = 0;"; + pidl "}"; + } } elsif ($l->{TYPE} eq "ARRAY") { pidl ParseExpr($e->{NAME}, $env) . " = $varname;"; } elsif ($l->{TYPE} eq "DATA") { @@ -245,7 +261,7 @@ sub GenerateEnvElement($$) if ($l->{TYPE} eq "DATA") { $env->{$e->{NAME}} = "v->$e->{NAME}"; } elsif ($l->{TYPE} eq "POINTER") { - $env->{"ptr_$e->{NAME}"} = "v->ptr_$e->{NAME}"; + $env->{"ptr$l->{POINTER_INDEX}_$e->{NAME}"} = "v->ptr$l->{POINTER_INDEX}_$e->{NAME}"; } elsif ($l->{TYPE} eq "SWITCH") { $env->{"level_$e->{NAME}"} = "v->level_$e->{NAME}"; } elsif ($l->{TYPE} eq "ARRAY") { @@ -350,7 +366,7 @@ sub UnionGenerateEnvElement($) if ($l->{TYPE} eq "DATA") { $env->{$e->{NAME}} = "v->u.$e->{NAME}"; } elsif ($l->{TYPE} eq "POINTER") { - $env->{"ptr_$e->{NAME}"} = "v->ptr"; + $env->{"ptr$l->{POINTER_INDEX}_$e->{NAME}"} = "v->ptr$l->{POINTER_INDEX}"; } elsif ($l->{TYPE} eq "SWITCH") { $env->{"level_$e->{NAME}"} = "v->level"; } elsif ($l->{TYPE} eq "ARRAY") { @@ -480,7 +496,7 @@ sub CreateFnDirection($$$$) pidl "prs_debug(ps, depth, desc, \"$fn\");"; pidl "depth++;"; - my $align = 0; + my $align = 8; foreach (@$es) { ParseElement($_, $env, PRIMITIVES, \$align); ParseElement($_, $env, DEFERRED, \$align); -- cgit