diff options
Diffstat (limited to 'tools/pidl/lib/Parse/Pidl/Samba3/Parser.pm')
-rw-r--r-- | tools/pidl/lib/Parse/Pidl/Samba3/Parser.pm | 86 |
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($) |