aboutsummaryrefslogtreecommitdiffstats
path: root/tools/pidl/lib/Parse/Pidl/Samba3/Parser.pm
diff options
context:
space:
mode:
Diffstat (limited to 'tools/pidl/lib/Parse/Pidl/Samba3/Parser.pm')
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba3/Parser.pm86
1 files changed, 51 insertions, 35 deletions
diff --git a/tools/pidl/lib/Parse/Pidl/Samba3/Parser.pm b/tools/pidl/lib/Parse/Pidl/Samba3/Parser.pm
index eaab50b553..9ef8f09dc4 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba3/Parser.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba3/Parser.pm
@@ -9,7 +9,7 @@ use strict;
use Parse::Pidl::Typelist qw(hasType getType mapType);
use Parse::Pidl::Util qw(has_property ParseExpr);
use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred);
-use Parse::Pidl::Samba3::Types qw(DeclShort DeclLong InitType DissectType);
+use Parse::Pidl::Samba3::Types qw(DeclShort DeclLong InitType DissectType StringType);
use vars qw($VERSION);
$VERSION = '0.01';
@@ -27,7 +27,7 @@ sub fatal($$) { my ($e,$s) = @_; die("$e->{FILE}:$e->{LINE}: $s\n"); }
#TODO:
# - Add some security checks (array sizes, memory alloc == NULL, etc)
# - Don't add seperate _p and _d functions if there is no deferred data
-# - [string]
+# - [string] with non-varying arrays and "surrounding" strings
# - subcontext()
# - DATA_BLOB
@@ -58,7 +58,7 @@ sub DeclareArrayVariables
next if ($l->{IS_DEFERRED} and $what == PRIMITIVES);
next if (not $l->{IS_DEFERRED} and $what == DEFERRED);
}
- if ($l->{TYPE} eq "ARRAY") {
+ if ($l->{TYPE} eq "ARRAY" and not $l->{IS_ZERO_TERMINATED}) {
pidl "uint32 i_$e->{NAME}_$l->{LEVEL_INDEX};";
$output = 1;
}
@@ -71,15 +71,7 @@ sub ParseElementLevelData($$$$$$$)
{
my ($e,$l,$nl,$env,$varname,$what,$align) = @_;
- my @args = ($e,$l,$varname,$what,$align);
-
- # See if we need to add a level argument because we're parsing a union
- foreach (@{$e->{LEVELS}}) {
- push (@args, ParseExpr("level_$e->{NAME}", $env))
- if ($_->{TYPE} eq "SWITCH");
- }
-
- my $c = DissectType(@args);
+ my $c = DissectType($e,$l,$varname,$what,$align);
return if not $c;
if (defined($e->{ALIGN})) {
@@ -98,9 +90,16 @@ sub ParseElementLevelArray($$$$$$$)
my ($e,$l,$nl,$env,$varname,$what,$align) = @_;
if ($l->{IS_ZERO_TERMINATED}) {
- fatal($e, "[string] attribute not supported for Samba3 yet");
+ return if ($what == DEFERRED);
- #FIXME
+ my ($t,$f) = StringType($e,$l);
+
+ Align($align, 4);
+ pidl "if (!smb_io_$t(\"$e->{NAME}\", &$varname, 1, ps, depth))";
+ pidl "\treturn False;";
+
+ $$align = 0;
+ return;
}
my $len = ParseExpr($l->{LENGTH_IS}, $env);
@@ -236,7 +235,9 @@ sub InitLevel($$$$)
indent;
}
- pidl ParseExpr("ptr$l->{POINTER_INDEX}_$e->{NAME}", $env) . " = 1;";
+ unless ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "TOP") {
+ pidl ParseExpr("ptr$l->{POINTER_INDEX}_$e->{NAME}", $env) . " = 1;";
+ }
InitLevel($e, GetNextLevel($e,$l), "*$varname", $env);
if ($l->{POINTER_TYPE} ne "ref") {
@@ -245,12 +246,16 @@ sub InitLevel($$$$)
pidl "\t" . ParseExpr("ptr$l->{POINTER_INDEX}_$e->{NAME}", $env) . " = 0;";
pidl "}";
}
+ } elsif ($l->{TYPE} eq "ARRAY" and $l->{IS_ZERO_TERMINATED}) {
+ my ($t,$f) = StringType($e,$l);
+ pidl "init_$t(&" . ParseExpr($e->{NAME}, $env) . ", ".substr($varname, 1) . ", $f);";
} elsif ($l->{TYPE} eq "ARRAY") {
pidl ParseExpr($e->{NAME}, $env) . " = $varname;";
} elsif ($l->{TYPE} eq "DATA") {
pidl InitType($e, $l, ParseExpr($e->{NAME}, $env), $varname);
} elsif ($l->{TYPE} eq "SWITCH") {
InitLevel($e, GetNextLevel($e,$l), $varname, $env);
+ pidl ParseExpr($e->{NAME}, $env) . ".switch_value = " . ParseExpr($l->{SWITCH_IS}, $env) . ";";
}
}
@@ -263,8 +268,7 @@ sub GenerateEnvElement($$)
} elsif ($l->{TYPE} eq "POINTER") {
$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") {
+ } elsif ($l->{TYPE} eq "ARRAY" and not $l->{IS_ZERO_TERMINATED}) {
$env->{"length_$e->{NAME}"} = "v->length_$e->{NAME}";
$env->{"size_$e->{NAME}"} = "v->size_$e->{NAME}";
$env->{"offset_$e->{NAME}"} = "v->offset_$e->{NAME}";
@@ -368,8 +372,7 @@ sub UnionGenerateEnvElement($)
} elsif ($l->{TYPE} eq "POINTER") {
$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") {
+ } elsif ($l->{TYPE} eq "ARRAY" and not $l->{IS_ZERO_TERMINATED}) {
$env->{"length_$e->{NAME}"} = "v->length";
$env->{"size_$e->{NAME}"} = "v->size";
$env->{"offset_$e->{NAME}"} = "v->offset";
@@ -389,20 +392,20 @@ sub ParseUnion($$$)
my $pfn = "$fn\_p";
my $dfn = "$fn\_d";
- pidl "BOOL $pfn(const char *desc, $sn* v, uint32 level, prs_struct *ps, int depth)";
+ pidl "BOOL $pfn(const char *desc, $sn* v, prs_struct *ps, int depth)";
pidl "{";
indent;
DeclareArrayVariables($u->{ELEMENTS});
- unless (has_property($u, "nodiscriminant")) {
- pidl "if (!prs_uint32(\"switch_value\", ps, depth, &v->switch_value))";
+ if (defined ($u->{SWITCH_TYPE})) {
+ pidl "if (!prs_$u->{SWITCH_TYPE}(\"switch_value\", ps, depth, &v->switch_value))";
pidl "\treturn False;";
pidl "";
}
# Maybe check here that level and v->switch_value are equal?
- pidl "switch (level) {";
+ pidl "switch (v->switch_value) {";
indent;
foreach (@{$u->{ELEMENTS}}) {
@@ -420,19 +423,30 @@ sub ParseUnion($$$)
pidl "";
}
+ unless ($u->{HAS_DEFAULT}) {
+ pidl "default:";
+ pidl "\treturn False;";
+ pidl "";
+ }
+
deindent;
pidl "}";
pidl "";
pidl "return True;";
deindent;
pidl "}";
+ pidl "";
- pidl "BOOL $dfn(const char *desc, $sn* v, uint32 level, prs_struct *ps, int depth)";
+ pidl "BOOL $dfn(const char *desc, $sn* v, prs_struct *ps, int depth)";
pidl "{";
indent;
DeclareArrayVariables($u->{ELEMENTS});
- pidl "switch (level) {";
+ if (defined($u->{SWITCH_TYPE})) {
+ pidl "switch (v->switch_value) {";
+ } else {
+ pidl "switch (level) {";
+ }
indent;
foreach (@{$u->{ELEMENTS}}) {
@@ -459,16 +473,14 @@ sub ParseUnion($$$)
}
-sub CreateFnDirection($$$$)
+sub CreateFnDirection($$$$$)
{
- my ($fn,$ifn, $s,$es) = @_;
+ my ($fn,$ifn,$s,$all,$es) = @_;
my $args = "";
- foreach (@$es) {
- $args .= ", " . DeclLong($_);
- }
+ foreach (@$all) { $args .= ", " . DeclLong($_); }
- my $env = { "this" => "v" };
+ my $env = { };
GenerateEnvElement($_, $env) foreach (@$es);
pidl "BOOL $ifn($s *v$args)";
@@ -515,6 +527,7 @@ sub ParseFunction($$)
my @in = ();
my @out = ();
+ my @all = @{$fn->{ELEMENTS}};
foreach (@{$fn->{ELEMENTS}}) {
push (@in, $_) if (grep(/in/, @{$_->{DIRECTION}}));
@@ -522,7 +535,7 @@ sub ParseFunction($$)
}
if (defined($fn->{RETURN_TYPE})) {
- push (@out, {
+ my $status = {
NAME => "status",
TYPE => $fn->{RETURN_TYPE},
LEVELS => [
@@ -531,17 +544,20 @@ sub ParseFunction($$)
DATA_TYPE => $fn->{RETURN_TYPE}
}
]
- } );
+ };
+
+ push (@out, $status);
+ push (@all, $status);
}
CreateFnDirection("$if->{NAME}_io_q_$fn->{NAME}",
"init_$if->{NAME}_q_$fn->{NAME}",
uc("$if->{NAME}_q_$fn->{NAME}"),
- \@in);
+ \@in, \@in);
CreateFnDirection("$if->{NAME}_io_r_$fn->{NAME}",
"init_$if->{NAME}_r_$fn->{NAME}",
uc("$if->{NAME}_r_$fn->{NAME}"),
- \@out);
+ \@all, \@out);
}
sub ParseInterface($)