mirror of
https://github.com/samba-team/samba.git
synced 2025-02-28 01:58:17 +03:00
r10742: Support multi-level pointers + ref pointer fixes
(This used to be commit 258b762dc62b257f99d1d859c5a3d850aba3e9fa)
This commit is contained in:
parent
765f69ce42
commit
be9af1a4e8
@ -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,10 +154,13 @@ 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");
|
||||
|
||||
|
@ -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}}));
|
||||
foreach my $e (@{$fn->{ELEMENTS}}) {
|
||||
next unless (grep(/out/, @{$e->{DIRECTION}}));
|
||||
|
||||
pidl "*$_->{NAME} = r.$_->{NAME};";
|
||||
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"";
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) . ") {";
|
||||
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);
|
||||
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") {
|
||||
if ($l->{POINTER_TYPE} eq "ref") {
|
||||
pidl "if (!$varname)";
|
||||
pidl "\treturn False;";
|
||||
pidl "";
|
||||
} else {
|
||||
pidl "if ($varname) {";
|
||||
indent;
|
||||
pidl ParseExpr("ptr_$e->{NAME}", $env) . " = 1;";
|
||||
}
|
||||
|
||||
pidl ParseExpr("ptr$l->{POINTER_INDEX}_$e->{NAME}", $env) . " = 1;";
|
||||
InitLevel($e, GetNextLevel($e,$l), "*$varname", $env);
|
||||
|
||||
if ($l->{POINTER_TYPE} ne "ref") {
|
||||
deindent;
|
||||
pidl "} else {";
|
||||
pidl "\t" . ParseExpr("ptr_$e->{NAME}", $env) . " = 0;";
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user