summaryrefslogtreecommitdiff
path: root/pidl/lib/Parse/Pidl/Samba4/SWIG.pm
diff options
context:
space:
mode:
Diffstat (limited to 'pidl/lib/Parse/Pidl/Samba4/SWIG.pm')
-rw-r--r--pidl/lib/Parse/Pidl/Samba4/SWIG.pm177
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 0000000000..14424cf260
--- /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;