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 [EMAIL PROTECTED] 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) {

Reply via email to