svn commit: samba r15437 - in branches/SAMBA_4_0/source/pidl: . lib/Parse/Pidl/Samba3

jelmer at samba.org jelmer at samba.org
Thu May 4 16:04:09 GMT 2006


Author: jelmer
Date: 2006-05-04 16:04:08 +0000 (Thu, 04 May 2006)
New Revision: 15437

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=15437

Log:
Add generator that creates Samba3 client code which uses Samba4's NDR 
routines.

Added:
   branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
Modified:
   branches/SAMBA_4_0/source/pidl/pidl


Changeset:
Added: branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
===================================================================
--- branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm	2006-05-04 14:54:31 UTC (rev 15436)
+++ branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm	2006-05-04 16:04:08 UTC (rev 15437)
@@ -0,0 +1,136 @@
+###################################################
+# Samba3 client generator for IDL structures
+# on top of Samba4 style NDR functions
+# Copyright jelmer at samba.org 2005-2006
+# released under the GNU GPL
+
+package Parse::Pidl::Samba3::ClientNDR;
+
+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(DeclLong);
+
+use vars qw($VERSION);
+$VERSION = '0.01';
+
+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"); }
+sub warning($$) { my ($e,$s) = @_; warn("$e->{ORIGINAL}->{FILE}:$e->{ORIGINAL}->{LINE}: $s\n"); }
+
+sub CopyLevel($$$$)
+{
+	sub CopyLevel($$$$);
+	my ($e,$l,$argument,$member) = @_;
+
+	if ($l->{TYPE} eq "DATA") {
+		pidl "*$argument = *$member;";
+	} elsif ($l->{TYPE} eq "POINTER") {
+		pidl "if (r.ptr$l->{POINTER_INDEX}_$e->{NAME}) {";
+		indent;
+		pidl "*$argument = talloc_size(mem_ctx, sizeof(void *));";
+		CopyLevel($e,GetNextLevel($e,$l),"*$argument", $member);
+		deindent;
+		pidl "}";
+	} elsif ($l->{TYPE} eq "SWITCH") {
+		CopyLevel($e,GetNextLevel($e,$l),$argument,$member);	
+	} elsif ($l->{TYPE} eq "ARRAY") {
+		pidl "*$argument = $member;";
+	}
+}
+
+sub ParseFunction($$)
+{
+	my ($if,$fn) = @_;
+
+	my $inargs = "";
+	my $defargs = "";
+	my $uif = uc($if->{NAME});
+	my $ufn = uc($fn->{NAME});
+
+	foreach (@{$fn->{ELEMENTS}}) {
+		$defargs .= ", " . DeclLong($_);
+	}
+	pidl "NTSTATUS rpccli_$fn->{NAME}(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx$defargs)";
+	pidl "{";
+	indent;
+	pidl "struct $fn->{NAME} r;";
+	pidl "NTSTATUS status;";
+	pidl "";
+	pidl "/* In parameters */";
+
+	foreach (@{$fn->{ELEMENTS}}) {
+		if (grep(/in/, @{$_->{DIRECTION}})) {
+			pidl "r.in.$_->{NAME} = $_->{NAME};";
+		} 
+	}
+
+	pidl "status = cli_do_rpc_ndr(cli, mem_ctx, PI_$uif, $ufn, &r, ndr_pull_$fn->{NAME}, ndr_push_$fn->{NAME});";
+	pidl "if (NT_STATUS_IS_ERR(status)) {";
+	pidl "\treturn status;";
+	pidl "}";
+	pidl "";
+	pidl "/* Return variables */";
+	foreach my $e (@{$fn->{ELEMENTS}}) {
+		next unless (grep(/out/, @{$e->{DIRECTION}}));
+
+		if ($e->{LEVELS}[0]->{TYPE} ne "POINTER") {
+			warning($e, "First element not a pointer for [out] argument");
+			next;
+		}
+
+		CopyLevel($e, $e->{LEVELS}[1], $e->{NAME}, "r.out.$e->{NAME}");
+	}
+
+	pidl"";
+	pidl "/* Return result */";
+	if (not $fn->{RETURN_TYPE}) {
+		pidl "return NT_STATUS_OK;";
+	} elsif ($fn->{RETURN_TYPE} eq "NTSTATUS") {
+		pidl "return r.status;";
+	} elsif ($fn->{RETURN_TYPE} eq "WERROR") {
+		pidl "return werror_to_ntstatus(r.status);";
+	} else {
+		pidl "/* Sorry, don't know how to convert $fn->{RETURN_TYPE} to NTSTATUS */";
+		pidl "return NT_STATUS_OK;";
+	}
+
+	deindent;
+	pidl "}";
+	pidl "";
+}
+
+sub ParseInterface($)
+{
+	my $if = shift;
+
+	ParseFunction($if, $_) foreach (@{$if->{FUNCTIONS}});
+}
+
+sub Parse($$)
+{
+	my($ndr,$filename) = @_;
+
+	$res = "";
+
+	pidl "/*";
+	pidl " * Unix SMB/CIFS implementation.";
+	pidl " * client auto-generated by pidl. DO NOT MODIFY!";
+	pidl " */";
+	pidl "";
+	pidl "#include \"includes.h\"";
+	pidl "";
+	
+	foreach (@$ndr) {
+		ParseInterface($_) if ($_->{TYPE} eq "INTERFACE");
+	}
+
+	return $res;
+}
+
+1;

Modified: branches/SAMBA_4_0/source/pidl/pidl
===================================================================
--- branches/SAMBA_4_0/source/pidl/pidl	2006-05-04 14:54:31 UTC (rev 15436)
+++ branches/SAMBA_4_0/source/pidl/pidl	2006-05-04 16:04:08 UTC (rev 15437)
@@ -17,7 +17,7 @@
 
 pidl --help
 
-pidl [--outputdir[=OUTNAME]] [--parse-idl-tree] [--dump-idl-tree] [--dump-ndr-tree] [--header[=OUTPUT]] [--ejs[=OUTPUT]] [--swig[=OUTPUT]] [--uint-enums] [--ndr-parser[=OUTPUT]] [--client] [--server] [--dcom-proxy] [--com-header] [--warn-compat] [--quiet] [--verbose] [--template] [--eth-parser[=OUTPUT]] [--diff] [--dump-idl] [--tdr-parser[=OUTPUT]] [--samba3-header[=OUTPUT]] [--samba3-parser=[OUTPUT]] [--samba3-server=[OUTPUT]] [--samba3-template[=OUTPUT]] [--samba3-client[=OUTPUT]] [<idlfile>.idl]...
+pidl [--outputdir[=OUTNAME]] [--parse-idl-tree] [--dump-idl-tree] [--dump-ndr-tree] [--header[=OUTPUT]] [--ejs[=OUTPUT]] [--swig[=OUTPUT]] [--uint-enums] [--ndr-parser[=OUTPUT]] [--client] [--server] [--dcom-proxy] [--com-header] [--warn-compat] [--quiet] [--verbose] [--template] [--eth-parser[=OUTPUT]] [--diff] [--dump-idl] [--tdr-parser[=OUTPUT]] [--samba3-header[=OUTPUT]] [--samba3-parser=[OUTPUT]] [--samba3-server=[OUTPUT]] [--samba3-template[=OUTPUT]] [--samba3-client[=OUTPUT]] [--samba3-ndr-client[=OUTPUT]] [<idlfile>.idl]...
 
 =head1 DESCRIPTION
 
@@ -144,6 +144,12 @@
 Generate client calls for Samba 3, to be placed in rpc_client/. Filename 
 defaults to cli_BASENAME.c.
 
+=item I<--samba3-ndr-client>
+
+Generate client calls for Samba3, to be placed in rpc_client/. Instead of 
+calling out to the code in Samba3's rpc_parse/, this will call out to 
+Samba4's NDR code instead.
+
 =back
 
 =head1 IDL SYNTAX
@@ -465,6 +471,7 @@
 my($opt_samba3_server);
 my($opt_samba3_template);
 my($opt_samba3_client);
+my($opt_samba3_ndr_client);
 my($opt_template) = 0;
 my($opt_client);
 my($opt_server);
@@ -523,6 +530,8 @@
  --samba3-template[=OUTF]create template implementation [srv_BASENAME_nt.c]
  --samba3-server[=OUTF]  create server side wrappers for Samba3 [srv_BASENAME.c]
  --samba3-client[=OUTF]  create client calls for Samba3 [cli_BASENAME.c]
+ --samba3-ndr-client[=OUTF] create client calls for Samba3 
+                            using Samba4's NDR code [cli_BASENAME.c]
 
 Ethereal parsers:
  --eth-parser[=OUTFILE]  create ethereal parser and header
@@ -544,6 +553,7 @@
 		'samba3-server:s' => \$opt_samba3_server,
 		'samba3-template:s' => \$opt_samba3_template,
 		'samba3-client:s' => \$opt_samba3_client,
+		'samba3-ndr-client:s' => \$opt_samba3_ndr_client,
 		'header:s' => \$opt_header,
 	    'server:s' => \$opt_server,
 	    'tdr-parser:s' => \$opt_tdr_parser,
@@ -570,6 +580,11 @@
     exit(0);
 }
 
+if ($opt_samba3_client and $opt_samba3_ndr_client) {
+	print "--samba3-client and --samba3-ndr-client can not be used together\n";
+	exit(1);
+}
+
 sub process_file($)
 {
 	my $idl_file = shift;
@@ -645,7 +660,8 @@
 	    defined($opt_ndr_parser) or defined($opt_ejs) or 
 		defined($opt_dump_ndr_tree) or defined($opt_samba3_header) or 
 	    defined($opt_samba3_parser) or defined($opt_samba3_server) or 
-		defined($opt_samba3_template) or defined($opt_samba3_client)) {
+		defined($opt_samba3_template) or defined($opt_samba3_client) or
+		defined($opt_samba3_ndr_client)) {
 		require Parse::Pidl::NDR;
 		$ndr = Parse::Pidl::NDR::Parse($pidl);
 	}
@@ -756,7 +772,7 @@
 
 	if (defined($opt_samba3_header) or defined($opt_samba3_parser) or
 		defined($opt_samba3_server) or defined($opt_samba3_client) or
-		defined($opt_samba3_template)) {
+		defined($opt_samba3_ndr_client) or defined($opt_samba3_template)) {
 		require Parse::Pidl::Samba3::Types;
 		Parse::Pidl::Samba3::Types::LoadTypes($ndr);
 	}
@@ -791,6 +807,13 @@
 		FileSave($header, Parse::Pidl::Samba3::Client::Parse($ndr, $basename));
 	}
 
+	if (defined($opt_samba3_ndr_client)) {
+		my $header = ($opt_samba3_ndr_client or "$outputdir/cli_$basename.c");
+		require Parse::Pidl::Samba3::ClientNDR;
+		FileSave($header, Parse::Pidl::Samba3::ClientNDR::Parse($ndr, $basename));
+	}
+
+
 }
 
 if (scalar(@ARGV) == 0) {



More information about the samba-cvs mailing list