Author: jelmer Date: 2005-10-05 22:18:59 +0000 (Wed, 05 Oct 2005) New Revision: 10742
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=10742 Log: Support multi-level pointers + ref pointer fixes Modified: branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/NDR.pm branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Client.pm branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Header.pm branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Parser.pm Changeset: Modified: branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/NDR.pm =================================================================== --- branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/NDR.pm 2005-10-05 21:52:33 UTC (rev 10741) +++ branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/NDR.pm 2005-10-05 22:18:59 UTC (rev 10742) @@ -80,6 +80,7 @@ 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 @@ 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"); Modified: branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Client.pm =================================================================== --- branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Client.pm 2005-10-05 21:52:33 UTC (rev 10741) +++ branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Client.pm 2005-10-05 22:18:59 UTC (rev 10742) @@ -20,7 +20,29 @@ 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($$) { my ($if,$fn) = @_; @@ -59,10 +81,14 @@ 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""; Modified: branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Header.pm =================================================================== --- branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Header.pm 2005-10-05 21:52:33 UTC (rev 10741) +++ branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Header.pm 2005-10-05 22:18:59 UTC (rev 10742) @@ -29,7 +29,7 @@ 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 @@ $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; } Modified: branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Parser.pm =================================================================== --- branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Parser.pm 2005-10-05 21:52:33 UTC (rev 10741) +++ branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Parser.pm 2005-10-05 22:18:59 UTC (rev 10742) @@ -158,14 +158,16 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ 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);