summaryrefslogtreecommitdiff
path: root/source4/pidl
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2005-10-05 22:18:59 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:39:26 -0500
commitbe9af1a4e8d474a544840f657b1be0c302986417 (patch)
tree305d1d2122fc3ad67130b1041245a4c7bd3df034 /source4/pidl
parent765f69ce42068cc2a41e010d08922a496da96054 (diff)
downloadsamba-be9af1a4e8d474a544840f657b1be0c302986417.tar.gz
samba-be9af1a4e8d474a544840f657b1be0c302986417.tar.bz2
samba-be9af1a4e8d474a544840f657b1be0c302986417.zip
r10742: Support multi-level pointers + ref pointer fixes
(This used to be commit 258b762dc62b257f99d1d859c5a3d850aba3e9fa)
Diffstat (limited to 'source4/pidl')
-rw-r--r--source4/pidl/lib/Parse/Pidl/NDR.pm4
-rw-r--r--source4/pidl/lib/Parse/Pidl/Samba3/Client.pm34
-rw-r--r--source4/pidl/lib/Parse/Pidl/Samba3/Header.pm4
-rw-r--r--source4/pidl/lib/Parse/Pidl/Samba3/Parser.pm54
4 files changed, 71 insertions, 25 deletions
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);