aboutsummaryrefslogtreecommitdiffstats
path: root/tools/pidl/lib/Parse/Pidl/Samba4/SWIG.pm
diff options
context:
space:
mode:
Diffstat (limited to 'tools/pidl/lib/Parse/Pidl/Samba4/SWIG.pm')
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba4/SWIG.pm195
1 files changed, 146 insertions, 49 deletions
diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/SWIG.pm b/tools/pidl/lib/Parse/Pidl/Samba4/SWIG.pm
index b6c268edeb..57ff007d1b 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba4/SWIG.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba4/SWIG.pm
@@ -1,79 +1,176 @@
###################################################
# 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(mapType);
+use Parse::Pidl::Util qw(has_property);
$VERSION = '0.01';
use strict;
+my $ret = "";
+my $tabs = "";
+
sub pidl($)
{
- print OUT shift;
+ my $p = shift;
+ $ret .= $tabs. $p . "\n";
}
-#####################################################################
-# rewrite autogenerated header file
-sub RewriteHeader($$$)
-{
- my($idl) = shift;
- my($input) = shift;
- my($output) = shift;
-
- open(IN, "<$input") || die "can't open $input for reading";
- open(OUT, ">$output") || die "can't open $output for writing";
-
- pidl "%{\n";
- pidl "#define data_in in\n";
- pidl "#define data_out out\n";
- pidl "%}\n\n";
-
- while(<IN>) {
+sub indent() { $tabs.="\t"; }
+sub deindent() { $tabs = substr($tabs,0,-1); }
- # Rename dom_sid2 to dom_sid as we don't care about the difference
- # for the swig wrappers.
-
- s/dom_sid2/dom_sid/g;
-
- # Copy structure and union definitions
+sub IgnoreInterface($$)
+{
+ my ($basename,$if) = @_;
- if (/^(struct|union) .*? {$/ .. /^\};$/) {
- s/\} (in|out);/\} data_$1;/; # "in" is a Python keyword
- pidl $_;
- next;
+ foreach (@{$if->{TYPES}}) {
+ next unless (has_property($_, "public"));
+ pidl "\%types($_->{NAME});";
}
+}
- # Copy dcerpc functions
-
- pidl $_ if /^NTSTATUS dcerpc_.*?\(struct dcerpc_pipe/;
-
- # Copy interface definitions
+sub ParseInterface($$)
+{
+ my ($basename,$if) = @_;
+
+ pidl "\%inline {";
+ pidl "struct $if->{NAME} { struct dcerpc_pipe *pipe; };";
+ pidl "}";
+ pidl "";
+ pidl "\%extend $if->{NAME} {";
+ indent();
+ pidl "$if->{NAME} (const char *binding, struct cli_credentials *cred = NULL, TALLOC_CTX *mem_ctx = NULL, struct event_context *event = NULL)";
+ pidl "{";
+ indent;
+ pidl "struct $if->{NAME} *ret = talloc(mem_ctx, struct $if->{NAME});";
+ pidl "NTSTATUS status;";
+ pidl "";
+ pidl "status = dcerpc_pipe_connect(mem_ctx, &ret->pipe, binding, &dcerpc_table_$if->{NAME}, cred, event);";
+ pidl "if (NT_STATUS_IS_ERR(status)) {";
+ pidl "\tntstatus_exception(status);";
+ pidl "\treturn NULL;";
+ pidl "}";
+ pidl "";
+ pidl "return ret;";
+ deindent;
+ pidl "}";
+ pidl "";
+ pidl "~$if->{NAME}() {";
+ pidl "\ttalloc_free(self);";
+ 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 = NULL";
+ pidl mapType($fn->{RETURN_TYPE}) . " $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)) {";
+ pidl "\tntstatus_exception(status);";
+ if (defined($fn->{RETURN_TYPE})) {
+ pidl "\treturn r.out.result;";
+ } else {
+ pidl "\treturn;";
+ }
+ 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 "return r.out.result;";
+ }
+ deindent;
+ pidl "}";
+ pidl "";
+ }
- pidl $_
- if /^\#define DCERPC_.*?_UUID/ or /^\#define DCERPC_.*?_VERSION/;
- }
+ deindent();
+ pidl "};";
+ pidl "";
- close(OUT);
+ foreach (@{$if->{TYPES}}) {
+ pidl "/* $_->{NAME} */";
+ }
+
+ pidl "";
}
-#####################################################################
-# rewrite autogenerated header file
-sub RewriteC($$$)
+sub Parse($$$$)
{
- my($idl) = shift;
- my($input) = shift;
- my($output) = shift;
+ 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 \"auth/credentials/credentials.h\"";
+ pidl "#include \"$header\"";
+ pidl "#include \"$gen_header\"";
+ pidl "%}";
+ pidl "\%import \"samba.i\"";
+ pidl "";
+ pidl "\%inline {";
+ pidl "void ntstatus_exception(NTSTATUS status)";
+ pidl "{";
+ pidl "\t/* FIXME */";
+ pidl "}";
+ pidl "}";
+ pidl "";
+ foreach (@$ndr) {
+ IgnoreInterface($basename, $_) if ($_->{TYPE} eq "INTERFACE");
+ }
+ pidl "";
- open(IN, "<$input") || die "can't open $input for reading";
- open(OUT, ">>$output") || die "can't open $output for writing";
-
- while(<IN>) {
- }
+ pidl "";
- close(OUT);
+ 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;