diff options
Diffstat (limited to 'source4/pidl/lib/Parse/Pidl/Samba3/Parser.pm')
-rw-r--r-- | source4/pidl/lib/Parse/Pidl/Samba3/Parser.pm | 603 |
1 files changed, 0 insertions, 603 deletions
diff --git a/source4/pidl/lib/Parse/Pidl/Samba3/Parser.pm b/source4/pidl/lib/Parse/Pidl/Samba3/Parser.pm deleted file mode 100644 index 57fa3867f7..0000000000 --- a/source4/pidl/lib/Parse/Pidl/Samba3/Parser.pm +++ /dev/null @@ -1,603 +0,0 @@ -################################################### -# Samba3 NDR parser generator for IDL structures -# Copyright jelmer@samba.org 2005 -# released under the GNU GPL - -package Parse::Pidl::Samba3::Parser; - -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 StringType); - -use vars qw($VERSION); -$VERSION = '0.01'; - -use constant PRIMITIVES => 1; -use constant DEFERRED => 2; - -my $res = ""; -my $tabs = ""; -sub indent() { $tabs.="\t"; } -sub deindent() { $tabs = substr($tabs, 1); } -sub pidl($) { $res .= $tabs.(shift)."\n"; } -sub fatal($$) { my ($e,$s) = @_; die("$e->{ORIGINAL}->{FILE}:$e->{ORIGINAL}->{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] with non-varying arrays and "surrounding" strings -# - subcontext() -# - DATA_BLOB - -sub Align($$) -{ - my ($a,$b) = @_; - - # Only align if previous element was smaller than current one - if ($$a < $b) { - pidl "if (!prs_align_custom(ps, $b))"; - pidl "\treturn False;"; - pidl ""; - } - - $$a = $b; -} - -sub DeclareArrayVariables -{ - my $es = shift; - my $what = shift; - - my $output = 0; - - foreach my $e (@$es) { - foreach my $l (@{$e->{LEVELS}}) { - if ($what) { - next if ($l->{IS_DEFERRED} and $what == PRIMITIVES); - next if (not $l->{IS_DEFERRED} and $what == DEFERRED); - } - if ($l->{TYPE} eq "ARRAY" and not $l->{IS_ZERO_TERMINATED}) { - pidl "uint32 i_$e->{NAME}_$l->{LEVEL_INDEX};"; - $output = 1; - } - } - } - pidl "" if $output; -} - -sub ParseElementLevelData($$$$$$$) -{ - my ($e,$l,$nl,$env,$varname,$what,$align) = @_; - - my $c = DissectType($e,$l,$varname,$what,$align); - return if not $c; - - if (defined($e->{ALIGN})) { - Align($align, $e->{ALIGN}); - } else { - # Default to 4 - Align($align, 4); - } - - pidl "if (!$c)"; - pidl "\treturn False;"; -} - -sub ParseElementLevelArray($$$$$$$) -{ - my ($e,$l,$nl,$env,$varname,$what,$align) = @_; - - if ($l->{IS_ZERO_TERMINATED}) { - return if ($what == DEFERRED); - - 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); - my $size = ParseExpr($l->{SIZE_IS}, $env); - - if ($what == PRIMITIVES) { - # Fetch headers - if ($l->{IS_CONFORMANT} and not $l->{IS_SURROUNDING}) { - Align($align, 4); - pidl "if (!prs_uint32(\"size_$e->{NAME}\", ps, depth, &" . ParseExpr("size_$e->{NAME}", $env) . "))"; - pidl "\treturn False;"; - pidl ""; - } - - if ($l->{IS_VARYING}) { - Align($align, 4); - pidl "if (!prs_uint32(\"offset_$e->{NAME}\", ps, depth, &" . ParseExpr("offset_$e->{NAME}", $env) . "))"; - pidl "\treturn False;"; - pidl ""; - - pidl "if (!prs_uint32(\"length_$e->{NAME}\", ps, depth, &" . ParseExpr("length_$e->{NAME}", $env) . "))"; - pidl "\treturn False;"; - pidl ""; - } - } - - # Everything but fixed arrays have to be allocated - if (!$l->{IS_FIXED} and $what == PRIMITIVES) { - pidl "if (UNMARSHALLING(ps)) {"; - indent; - pidl "$varname = (void *)PRS_ALLOC_MEM_VOID(ps,sizeof(*$varname)*$size);"; - deindent; - pidl "}"; - } - - return if ($what == DEFERRED and not ContainsDeferred($e,$l)); - - my $i = "i_$e->{NAME}_$l->{LEVEL_INDEX}"; - pidl "for ($i=0; $i<$len;$i++) {"; - indent; - ParseElementLevel($e,$nl,$env,$varname."[$i]",$what,$align); - deindent; - pidl "}"; -} - -sub ParseElementLevelSwitch($$$$$$$) -{ - my ($e,$l,$nl,$env,$varname,$what,$align) = @_; - - ParseElementLevel($e,$nl,$env,$varname,$what,$align); -} - -sub ParseElementLevelPtr($$$$$$$) -{ - my ($e,$l,$nl,$env,$varname,$what,$align) = @_; - - if ($what == PRIMITIVES) { - 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 ""; - } - - unless ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "TOP") { - Align($align, 4); - 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 ($l->{POINTER_TYPE} eq "relative") { - fatal($e, "relative pointers not supported for Samba 3"); - #FIXME - } - - if ($what == DEFERRED) { - 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; - } -} - -sub ParseElementLevelSubcontext($$$$$$$) -{ - my ($e,$l,$nl,$env,$varname,$what,$align) = @_; - - fatal($e, "subcontext() not supported for Samba 3"); - #FIXME -} - -sub ParseElementLevel($$$$$$) -{ - my ($e,$l,$env,$varname,$what,$align) = @_; - - { - DATA => \&ParseElementLevelData, - SUBCONTEXT => \&ParseElementLevelSubcontext, - POINTER => \&ParseElementLevelPtr, - SWITCH => \&ParseElementLevelSwitch, - ARRAY => \&ParseElementLevelArray - }->{$l->{TYPE}}->($e,$l,GetNextLevel($e,$l),$env,$varname,$what,$align); -} - -sub ParseElement($$$$) -{ - my ($e,$env,$what,$align) = @_; - - ParseElementLevel($e, $e->{LEVELS}[0], $env, ParseExpr($e->{NAME}, $env), $what, $align); -} - -sub InitLevel($$$$) -{ - 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; - } - - 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") { - deindent; - pidl "} else {"; - 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) . ";"; - } -} - -sub GenerateEnvElement($$) -{ - my ($e,$env) = @_; - foreach my $l (@{$e->{LEVELS}}) { - if ($l->{TYPE} eq "DATA") { - $env->{$e->{NAME}} = "v->$e->{NAME}"; - } elsif ($l->{TYPE} eq "POINTER") { - $env->{"ptr$l->{POINTER_INDEX}_$e->{NAME}"} = "v->ptr$l->{POINTER_INDEX}_$e->{NAME}"; - } elsif ($l->{TYPE} eq "SWITCH") { - } 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}"; - } - } -} - -sub ParseStruct($$$) -{ - my ($if,$s,$n) = @_; - - my $fn = "$if->{NAME}_io_$n"; - my $sn = uc("$if->{NAME}_$n"); - my $ifn = "init_$if->{NAME}_$n"; - - my $args = ""; - foreach (@{$s->{ELEMENTS}}) { - $args .= ", " . DeclLong($_); - } - - my $env = { "this" => "v" }; - GenerateEnvElement($_, $env) foreach (@{$s->{ELEMENTS}}); - - pidl "BOOL $ifn($sn *v$args)"; - pidl "{"; - indent; - pidl "DEBUG(5,(\"$ifn\\n\"));"; - pidl ""; - # Call init for all arguments - foreach (@{$s->{ELEMENTS}}) { - InitLevel($_, $_->{LEVELS}[0], $_->{NAME}, $env); - pidl ""; - } - pidl "return True;"; - deindent; - pidl "}"; - pidl ""; - - my $pfn = "$fn\_p"; - my $dfn = "$fn\_d"; - - pidl "BOOL $pfn(const char *desc, $sn *v, prs_struct *ps, int depth)"; - pidl "{"; - indent; - DeclareArrayVariables($s->{ELEMENTS}, PRIMITIVES); - pidl "if (v == NULL)"; - pidl "\treturn False;"; - pidl ""; - pidl "prs_debug(ps, depth, desc, \"$pfn\");"; - pidl "depth++;"; - - my $align = 8; - if ($s->{SURROUNDING_ELEMENT}) { - pidl "if (!prs_uint32(\"size_$s->{SURROUNDING_ELEMENT}->{NAME}\", ps, depth, &" . ParseExpr("size_$s->{SURROUNDING_ELEMENT}->{NAME}", $env) . "))"; - pidl "\treturn False;"; - pidl ""; - $align = 4; - - } - - foreach (@{$s->{ELEMENTS}}) { - ParseElement($_, $env, PRIMITIVES, \$align); - pidl ""; - } - - pidl "return True;"; - deindent; - pidl "}"; - pidl ""; - - pidl "BOOL $dfn(const char *desc, $sn *v, prs_struct *ps, int depth)"; - pidl "{"; - indent; - DeclareArrayVariables($s->{ELEMENTS}, DEFERRED); - pidl "if (v == NULL)"; - pidl "\treturn False;"; - pidl ""; - pidl "prs_debug(ps, depth, desc, \"$dfn\");"; - pidl "depth++;"; - - $align = 0; - foreach (@{$s->{ELEMENTS}}) { - ParseElement($_, $env, DEFERRED, \$align); - pidl ""; - } - - pidl "return True;"; - deindent; - pidl "}"; - pidl ""; -} - -sub UnionGenerateEnvElement($) -{ - my $e = shift; - my $env = {}; - - foreach my $l (@{$e->{LEVELS}}) { - if ($l->{TYPE} eq "DATA") { - $env->{$e->{NAME}} = "v->u.$e->{NAME}"; - } elsif ($l->{TYPE} eq "POINTER") { - $env->{"ptr$l->{POINTER_INDEX}_$e->{NAME}"} = "v->ptr$l->{POINTER_INDEX}"; - } elsif ($l->{TYPE} eq "SWITCH") { - } 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"; - } - } - - return $env; -} - -sub ParseUnion($$$) -{ - my ($if,$u,$n) = @_; - - my $fn = "$if->{NAME}_io_$n"; - my $sn = uc("$if->{NAME}_$n\_ctr"); - - my $pfn = "$fn\_p"; - my $dfn = "$fn\_d"; - - pidl "BOOL $pfn(const char *desc, $sn* v, prs_struct *ps, int depth)"; - pidl "{"; - indent; - DeclareArrayVariables($u->{ELEMENTS}); - - 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 (v->switch_value) {"; - indent; - - foreach (@{$u->{ELEMENTS}}) { - pidl "$_->{CASE}:"; - indent; - if ($_->{TYPE} ne "EMPTY") { - pidl "depth++;"; - my $env = UnionGenerateEnvElement($_); - my $align = 8; - ParseElement($_, $env, PRIMITIVES, \$align); - pidl "depth--;"; - } - pidl "break;"; - deindent; - 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, prs_struct *ps, int depth)"; - pidl "{"; - indent; - DeclareArrayVariables($u->{ELEMENTS}); - - if (defined($u->{SWITCH_TYPE})) { - pidl "switch (v->switch_value) {"; - } else { - pidl "switch (level) {"; - } - indent; - - foreach (@{$u->{ELEMENTS}}) { - pidl "$_->{CASE}:"; - indent; - if ($_->{TYPE} ne "EMPTY") { - pidl "depth++;"; - my $env = UnionGenerateEnvElement($_); - my $align = 0; - ParseElement($_, $env, DEFERRED, \$align); - pidl "depth--;"; - } - pidl "break;"; - deindent; - pidl ""; - } - - deindent; - pidl "}"; - pidl ""; - pidl "return True;"; - deindent; - pidl "}"; - -} - -sub CreateFnDirection($$$$$) -{ - my ($fn,$ifn,$s,$all,$es) = @_; - - my $args = ""; - foreach (@$all) { $args .= ", " . DeclLong($_); } - - my $env = { }; - GenerateEnvElement($_, $env) foreach (@$es); - - pidl "BOOL $ifn($s *v$args)"; - pidl "{"; - indent; - pidl "DEBUG(5,(\"$ifn\\n\"));"; - pidl ""; - # Call init for all arguments - foreach (@$es) { - InitLevel($_, $_->{LEVELS}[0], $_->{NAME}, $env); - pidl ""; - } - pidl "return True;"; - deindent; - pidl "}"; - pidl ""; - - pidl "BOOL $fn(const char *desc, $s *v, prs_struct *ps, int depth)"; - pidl "{"; - indent; - DeclareArrayVariables($es); - pidl "if (v == NULL)"; - pidl "\treturn False;"; - pidl ""; - pidl "prs_debug(ps, depth, desc, \"$fn\");"; - pidl "depth++;"; - - my $align = 8; - foreach (@$es) { - ParseElement($_, $env, PRIMITIVES, \$align); - ParseElement($_, $env, DEFERRED, \$align); - pidl ""; - } - - pidl "return True;"; - deindent; - pidl "}"; - pidl ""; -} - -sub ParseFunction($$) -{ - my ($if,$fn) = @_; - - my @in = (); - my @out = (); - my @all = @{$fn->{ELEMENTS}}; - - foreach (@{$fn->{ELEMENTS}}) { - push (@in, $_) if (grep(/in/, @{$_->{DIRECTION}})); - push (@out, $_) if (grep(/out/, @{$_->{DIRECTION}})); - } - - if (defined($fn->{RETURN_TYPE})) { - my $status = { - NAME => "status", - TYPE => $fn->{RETURN_TYPE}, - LEVELS => [ - { - TYPE => "DATA", - 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); - CreateFnDirection("$if->{NAME}_io_r_$fn->{NAME}", - "init_$if->{NAME}_r_$fn->{NAME}", - uc("$if->{NAME}_r_$fn->{NAME}"), - \@all, \@out); -} - -sub ParseInterface($) -{ - my $if = shift; - - # Structures first - pidl "/* $if->{NAME} structures */"; - foreach (@{$if->{TYPES}}) { - ParseStruct($if, $_->{DATA}, $_->{NAME}) if ($_->{DATA}->{TYPE} eq "STRUCT"); - ParseUnion($if, $_->{DATA}, $_->{NAME}) if ($_->{DATA}->{TYPE} eq "UNION"); - } - - pidl "/* $if->{NAME} functions */"; - ParseFunction($if, $_) foreach (@{$if->{FUNCTIONS}}); -} - -sub Parse($$) -{ - my($ndr,$filename) = @_; - - $tabs = ""; - $res = ""; - - pidl "/*"; - pidl " * Unix SMB/CIFS implementation."; - pidl " * parser auto-generated by pidl. DO NOT MODIFY!"; - pidl " */"; - pidl ""; - pidl "#include \"includes.h\""; - pidl ""; - pidl "#undef DBGC_CLASS"; - pidl "#define DBGC_CLASS DBGC_RPC_PARSE"; - pidl ""; - - foreach (@$ndr) { - ParseInterface($_) if ($_->{TYPE} eq "INTERFACE"); - } - - return $res; -} - -1; |