################################################### # 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;