diff options
Diffstat (limited to 'pidl/lib/Parse/Pidl/Samba4/SWIG.pm')
-rw-r--r-- | pidl/lib/Parse/Pidl/Samba4/SWIG.pm | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/pidl/lib/Parse/Pidl/Samba4/SWIG.pm b/pidl/lib/Parse/Pidl/Samba4/SWIG.pm new file mode 100644 index 00000000000..14424cf2604 --- /dev/null +++ b/pidl/lib/Parse/Pidl/Samba4/SWIG.pm @@ -0,0 +1,177 @@ +################################################### +# Samba4 parser generator for swig wrappers +# Copyright tpot@samba.org 2004,2005 +# Copyright jelmer@samba.org 2006 +# released under the GNU GPL + +package Parse::Pidl::Samba4::SWIG; + +use vars qw($VERSION); +use Parse::Pidl::Samba4 qw(DeclLong); +use Parse::Pidl::Typelist qw(mapTypeName); +use Parse::Pidl::Util qw(has_property); +$VERSION = '0.01'; + +use strict; + +my $ret = ""; +my $tabs = ""; + +sub pidl($) +{ + my $p = shift; + $ret .= $tabs. $p . "\n"; +} + +sub indent() { $tabs.=" "; } +sub deindent() { $tabs = substr($tabs,0,-2); } + +sub IgnoreInterface($$) +{ + my ($basename,$if) = @_; + + foreach (@{$if->{TYPES}}) { + next unless (has_property($_, "public")); + pidl "\%types($_->{NAME});"; + } +} + +sub GenerateResultTypemap($) +{ + my $name = shift; + pidl "%typemap(in,numinputs=0) $name*result ($name tmp) {"; + indent; + pidl "\$1 = &tmp;"; + deindent; + pidl "}"; + pidl ""; + pidl "%typemap(argout) $name*result {"; + indent; + pidl "\$result = SWIG_NewPointerObj(*\$1, \$1_descriptor, 0);"; + deindent; + pidl "}"; +} + +sub ParseInterface($$) +{ + my ($basename,$if) = @_; + + pidl "\%inline {"; + pidl "typedef struct $if->{NAME} { struct dcerpc_pipe *pipe; } $if->{NAME};"; + pidl "}"; + pidl ""; + pidl "%talloctype($if->{NAME});"; + pidl ""; + pidl "\%extend $if->{NAME} {"; + indent(); + pidl "$if->{NAME} () {"; + indent; + pidl "return talloc(NULL, struct $if->{NAME});"; + deindent; + pidl "}"; + pidl ""; + pidl "NTSTATUS connect (const char *binding, struct cli_credentials *cred, struct event_context *event)"; + pidl "{"; + indent; + pidl "return dcerpc_pipe_connect(\$self, &\$self->pipe, binding, &ndr_table_$if->{NAME}, cred, event);"; + deindent; + pidl "}"; + pidl ""; + + foreach my $fn (@{$if->{FUNCTIONS}}) { + pidl "/* $fn->{NAME} */"; + my $args = ""; + foreach (@{$fn->{ELEMENTS}}) { + $args .= DeclLong($_) . ", "; + } + my $name = $fn->{NAME}; + $name =~ s/^$if->{NAME}_//g; + $name =~ s/^$basename\_//g; + $args .= "TALLOC_CTX *mem_ctx, " . mapTypeName($fn->{RETURN_TYPE}) . " *result"; + pidl "NTSTATUS $name($args)"; + pidl "{"; + indent; + pidl "struct $fn->{NAME} r;"; + pidl "NTSTATUS status;"; + pidl ""; + pidl "/* Fill r structure */"; + + foreach (@{$fn->{ELEMENTS}}) { + if (grep(/in/, @{$_->{DIRECTION}})) { + pidl "r.in.$_->{NAME} = $_->{NAME};"; + } + } + + pidl ""; + pidl "status = dcerpc_$fn->{NAME}(\$self->pipe, mem_ctx, &r);"; + pidl "if (NT_STATUS_IS_ERR(status)) {"; + indent; pidl "return status;"; deindent; + pidl "}"; + pidl ""; + pidl "/* Set out arguments */"; + foreach (@{$fn->{ELEMENTS}}) { + next unless (grep(/out/, @{$_->{DIRECTION}})); + + pidl ("/* FIXME: $_->{NAME} [out] argument is not a pointer */") if ($_->{LEVELS}[0]->{TYPE} ne "POINTER"); + + pidl "*$_->{NAME} = *r.out.$_->{NAME};"; + } + + if (defined($fn->{RETURN_TYPE})) { + pidl "*result = r.out.result;"; + } + pidl "return NT_STATUS_OK;"; + deindent; + pidl "}"; + pidl ""; + } + + deindent(); + pidl "};"; + pidl ""; + + foreach (@{$if->{TYPES}}) { + pidl "/* $_->{NAME} */"; + } + + pidl ""; +} + +sub Parse($$$$) +{ + my($ndr,$basename,$header,$gen_header) = @_; + + $ret = ""; + + pidl "/* This file is autogenerated by pidl. DO NOT EDIT */"; + + pidl "\%module $basename"; + + pidl ""; + + pidl "\%{"; + pidl "#include \"includes.h\""; + pidl "#include \"$header\""; + pidl "#include \"$gen_header\""; + pidl "%}"; + pidl "\%import \"../rpc/dcerpc.i\""; + pidl "\%import \"../../libcli/util/errors.i\""; + pidl "\%import \"../../lib/talloc/talloc.i\""; + pidl ""; + foreach (@$ndr) { + IgnoreInterface($basename, $_) if ($_->{TYPE} eq "INTERFACE"); + } + pidl ""; + + pidl ""; + + foreach (@$ndr) { + ParseInterface($basename, $_) if ($_->{TYPE} eq "INTERFACE"); + } + #FIXME: Foreach ref pointer, set NONNULL + #FIXME: Foreach unique/full pointer, set MAYBENULL + #FIXME: Foreach [out] parameter, set OUTPARAM + return $ret; +} + +1; |