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($$)
{
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"";
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 "";
}
}
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;
}
}
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") {
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") {
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") {
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);