r7098: - make use of the NDR table instead of the IDL table in the client and server...
authorStefan Metzmacher <metze@samba.org>
Mon, 30 May 2005 09:07:21 +0000 (09:07 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:17:16 +0000 (13:17 -0500)
- add 'noid' property to allow functions to be not present in the function table,
  and not generate client and server functions for them
- print out a warning about [id()] not being correctly supported yet

metze

source/build/pidl/ndr.pm
source/build/pidl/ndr_client.pm
source/build/pidl/ndr_header.pm
source/build/pidl/ndr_parser.pm
source/build/pidl/pidl.pl
source/build/pidl/server.pm
source/build/pidl/validator.pm

index aa1a557dd199c2d656f468be473c40c63ef609c4..5fafab3cd0098478b5a32e66051fe1c580b88b16 100644 (file)
@@ -445,11 +445,17 @@ sub ParseFunction($$$)
        my $opnum = shift;
        my @elements = ();
        my $rettype = undef;
+       my $thisopnum = undef;
 
        CheckPointerTypes($d, 
                $ndr->{PROPERTIES}->{pointer_default_top}
        );
 
+       if (not defined($d->{PROPERTIES}{noid})) {
+               $thisopnum = ${$opnum};
+               ${$opnum}++;
+       }
+
        foreach my $x (@{$d->{ELEMENTS}}) {
                my $e = ParseElement($x);
                if (util::has_property($x, "in")) {
@@ -470,7 +476,7 @@ sub ParseFunction($$$)
        return {
                        NAME => $d->{NAME},
                        TYPE => "FUNCTION",
-                       OPNUM => $opnum,
+                       OPNUM => $thisopnum,
                        RETURN_TYPE => $rettype,
                        PROPERTIES => $d->{PROPERTIES},
                        ELEMENTS => \@elements
@@ -526,8 +532,7 @@ sub ParseInterface($)
                }
 
                if ($d->{TYPE} eq "FUNCTION") {
-                       push (@functions, ParseFunction($idl, $d, $opnum));
-                       $opnum+=1;
+                       push (@functions, ParseFunction($idl, $d, \$opnum));
                }
 
                if ($d->{TYPE} eq "CONST") {
index ca6fc22465923d995f26ee7cc175751ac730a22e..eb7d73b991b0eeb49215444284ebce40b4fed637 100644 (file)
@@ -42,7 +42,8 @@ NTSTATUS dcerpc_$name(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *
                NDR_PRINT_OUT_DEBUG($name, r);          
        }
 ";
-        if ($fn->{RETURN_TYPE} eq "NTSTATUS") {
+    
+        if (defined($fn->{RETURN_TYPE}) and $fn->{RETURN_TYPE} eq "NTSTATUS") {
              $res .= "\tif (NT_STATUS_IS_OK(status)) status = r->out.result;\n";
         }
        $res .= 
@@ -59,15 +60,40 @@ my %done;
 sub ParseInterface($)
 {
        my($interface) = shift;
-       my($data) = $interface->{DATA};
-       $res = "/* Client functions generated by pidl */\n\n";
-       
-       foreach my $d (@{$data}) {
-               if (($d->{TYPE} eq "FUNCTION") and not $done{$d->{NAME}}) {
-                       ParseFunction($interface, $d);
-               }
-               $done{$d->{NAME}} = 1;
+       $res .= "/* $interface->{NAME} - client functions generated by pidl */\n\n";
+
+       foreach my $fn (@{$interface->{FUNCTIONS}}) {
+               next if not defined($fn->{OPNUM});
+               next if defined($done{$fn->{NAME}});
+               ParseFunction($interface, $fn);
+               $done{$fn->{NAME}} = 1;
+       }
+
+       return $res;
+}
+
+sub Parse($$)
+{
+       my($ndr) = shift;
+       my($filename) = shift;
+
+       my $h_filename = $filename;
+       $res = "";
+
+       if ($h_filename =~ /(.*)\.c/) {
+               $h_filename = "$1.h";
        }
+
+       $res .= "/* client functions auto-generated by pidl */\n";
+       $res .= "\n";
+       $res .= "#include \"includes.h\"\n";
+       $res .= "#include \"$h_filename\"\n";
+       $res .= "\n";
+
+       foreach my $x (@{$ndr}) {
+               ($x->{TYPE} eq "INTERFACE") && ParseInterface($x);
+       }
+
        return $res;
 }
 
index dfc20389eac1a78f158e5eb0f7c7837235a4d21a..429f603f88616d6f90cfb47b217581193fa0f1eb 100644 (file)
@@ -334,68 +334,75 @@ sub HeaderFunction($)
 sub HeaderFnProto($$)
 {
        my $interface = shift;
-    my $fn = shift;
-    my $name = $fn->{NAME};
-       
-    pidl "void ndr_print_$name(struct ndr_print *ndr, const char *name, int flags, struct $name *r);\n";
+       my $fn = shift;
+       my $name = $fn->{NAME};
+
+       pidl "void ndr_print_$name(struct ndr_print *ndr, const char *name, int flags, struct $name *r);\n";
 
-    pidl "NTSTATUS dcerpc_$name(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r);\n";
-       pidl "struct rpc_request *dcerpc_$name\_send(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r);\n";
+       if (defined($fn->{OPNUM})) {
+               pidl "NTSTATUS dcerpc_$name(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r);\n";
+               pidl "struct rpc_request *dcerpc_$name\_send(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r);\n";
+       }
 
-    return unless util::has_property($fn, "public");
+       return unless util::has_property($fn, "public");
 
        pidl "NTSTATUS ndr_push_$name(struct ndr_push *ndr, int flags, struct $name *r);\n";
        pidl "NTSTATUS ndr_pull_$name(struct ndr_pull *ndr, int flags, struct $name *r);\n";
 
-    pidl "\n";
+       pidl "\n";
 }
 
 #####################################################################
 # parse the interface definitions
 sub HeaderInterface($)
 {
-    my($interface) = shift;
+       my($interface) = shift;
 
-    my $count = 0;
+       my $count = 0;
 
-    pidl "#ifndef _HEADER_NDR_$interface->{NAME}\n";
-    pidl "#define _HEADER_NDR_$interface->{NAME}\n\n";
+       pidl "#ifndef _HEADER_NDR_$interface->{NAME}\n";
+       pidl "#define _HEADER_NDR_$interface->{NAME}\n\n";
 
-    if (defined $interface->{PROPERTIES}->{depends}) {
-           my @d = split / /, $interface->{PROPERTIES}->{depends};
-           foreach my $i (@d) {
-                   pidl "#include \"librpc/gen_ndr/ndr_$i\.h\"\n";
-           }
-    }
+       if (defined $interface->{PROPERTIES}->{depends}) {
+               my @d = split / /, $interface->{PROPERTIES}->{depends};
+               foreach my $i (@d) {
+                       pidl "#include \"librpc/gen_ndr/ndr_$i\.h\"\n";
+               }
+       }
 
-    if (defined $interface->{PROPERTIES}->{uuid}) {
-           my $name = uc $interface->{NAME};
-           pidl "#define DCERPC_$name\_UUID " . 
+       if (defined $interface->{PROPERTIES}->{uuid}) {
+               my $name = uc $interface->{NAME};
+               pidl "#define DCERPC_$name\_UUID " . 
                util::make_str($interface->{PROPERTIES}->{uuid}) . "\n";
 
                if(!defined $interface->{PROPERTIES}->{version}) { $interface->{PROPERTIES}->{version} = "0.0"; }
-           pidl "#define DCERPC_$name\_VERSION $interface->{PROPERTIES}->{version}\n";
+               pidl "#define DCERPC_$name\_VERSION $interface->{PROPERTIES}->{version}\n";
 
-           pidl "#define DCERPC_$name\_NAME \"$interface->{NAME}\"\n";
+               pidl "#define DCERPC_$name\_NAME \"$interface->{NAME}\"\n";
 
                if(!defined $interface->{PROPERTIES}->{helpstring}) { $interface->{PROPERTIES}->{helpstring} = "NULL"; }
                pidl "#define DCERPC_$name\_HELPSTRING $interface->{PROPERTIES}->{helpstring}\n";
 
-           pidl "\nextern const struct dcerpc_interface_table dcerpc_table_$interface->{NAME};\n";
-           pidl "NTSTATUS dcerpc_server_$interface->{NAME}_init(void);\n\n";
-    }
+               pidl "\nextern const struct dcerpc_interface_table dcerpc_table_$interface->{NAME};\n";
+               pidl "NTSTATUS dcerpc_server_$interface->{NAME}_init(void);\n\n";
+       }
 
-    foreach my $d (@{$interface->{FUNCTIONS}}) {
-           my $u_name = uc $d->{NAME};
+       foreach my $d (@{$interface->{FUNCTIONS}}) {
+               next if not defined($d->{OPNUM});
+               my $u_name = uc $d->{NAME};
                pidl "#define DCERPC_$u_name (";
        
                if (defined($interface->{BASE})) {
                        pidl "DCERPC_" . uc $interface->{BASE} . "_CALL_COUNT + ";
                }
-               
-           pidl sprintf("0x%02x", $count) . ")\n";
-           $count++;
-    }
+
+               if ($d->{OPNUM} != $count) {
+                       die ("Function ".$d->{NAME}." has: wrong opnum [".$d->{OPNUM}."] should be [".$count."]");
+               }
+
+               pidl sprintf("0x%02x", $count) . ")\n";
+               $count++;
+       }
 
        pidl "\n#define DCERPC_" . uc $interface->{NAME} . "_CALL_COUNT (";
        
@@ -406,21 +413,20 @@ sub HeaderInterface($)
        pidl "$count)\n\n";
 
        foreach my $d (@{$interface->{CONSTS}}) {
-           HeaderConst($d);
-    }
+               HeaderConst($d);
+       }
 
-    foreach my $d (@{$interface->{TYPEDEFS}}) {
-           HeaderTypedef($d);
-           HeaderTypedefProto($d);
+       foreach my $d (@{$interface->{TYPEDEFS}}) {
+               HeaderTypedef($d);
+               HeaderTypedefProto($d);
        }
 
-    foreach my $d (@{$interface->{FUNCTIONS}}) {
-           HeaderFunction($d);
-           HeaderFnProto($interface, $d);
+       foreach my $d (@{$interface->{FUNCTIONS}}) {
+               HeaderFunction($d);
+               HeaderFnProto($interface, $d);
        }
 
-  
-    pidl "#endif /* _HEADER_NDR_$interface->{NAME} */\n";
+       pidl "#endif /* _HEADER_NDR_$interface->{NAME} */\n";
 }
 
 #####################################################################
index a73675159b5f9547b9c2d1284b1ea2d5468752a7..edc6df31ad4d1fb9d982b5b4e8b288d221c16839 100644 (file)
@@ -2061,7 +2061,9 @@ sub FunctionTable($)
        return if ($count == 0);
 
        pidl "static const struct dcerpc_interface_call $interface->{NAME}\_calls[] = {";
+       $count = 0;
        foreach my $d (@{$interface->{FUNCTIONS}}) {
+               next if not defined($d->{OPNUM});
                pidl "\t{";
                pidl "\t\t\"$d->{NAME}\",";
                pidl "\t\tsizeof(struct $d->{NAME}),";
@@ -2069,6 +2071,7 @@ sub FunctionTable($)
                pidl "\t\t(ndr_pull_flags_fn_t) ndr_pull_$d->{NAME},";
                pidl "\t\t(ndr_print_function_t) ndr_print_$d->{NAME}";
                pidl "\t},";
+               $count++;
        }
        pidl "\t{ NULL, 0, NULL, NULL, NULL }";
        pidl "};";
index 478c7a273a912aeb19d6e4f8428497f497ab32bd..a1089f90b1c23982a1d7b9f0f9aaa29485f47c92 100755 (executable)
@@ -220,22 +220,13 @@ sub process_file($)
 
        if ($opt_client) {
                my ($client) = util::ChangeExtension($output, "_c.c");
-               my $res = "";
                my $h_filename = util::ChangeExtension($output, ".h");
 
-               $res .= "#include \"includes.h\"\n";
-               $res .= "#include \"$h_filename\"\n\n";
-
-               foreach my $x (@{$pidl}) {
-                       $res .= NdrClient::ParseInterface($x);
-               }
-
-               util::FileSave($client, $res);
+               util::FileSave($client, NdrClient::Parse($ndr,$h_filename));
        }
 
        if ($opt_server) {
                my $h_filename = util::ChangeExtension($output, ".h");
-               my $plain = "";
                my $dcom = "";
 
                foreach my $x (@{$pidl}) {
@@ -243,14 +234,10 @@ sub process_file($)
 
                        if (util::has_property($x, "object")) {
                                $dcom .= DCOMStub::ParseInterface($x);
-                       } else {
-                               $plain .= IdlServer::ParseInterface($x);
                        }
                }
 
-               if ($plain ne "") {
-                       util::FileSave(util::ChangeExtension($output, "_s.c"), $plain);
-               }
+               util::FileSave(util::ChangeExtension($output, "_s.c"), NdrServer::Parse($ndr,$h_filename));
 
                if ($dcom ne "") {
                        $dcom = "
index 46dada7c7f9a543b41c73116409721ecddc84829..29745686fed6b654b0d39827531315f5ceb4d011 100644 (file)
@@ -4,7 +4,7 @@
 # Copyright metze@samba.org 2004
 # released under the GNU GPL
 
-package IdlServer;
+package NdrServer;
 
 use strict;
 
@@ -20,27 +20,25 @@ sub pidl($)
 # generate the switch statement for function dispatch
 sub gen_dispatch_switch($)
 {
-       my $data = shift;
+       my $interface = shift;
 
-       my $count = 0;
-       foreach my $d (@{$data}) {
-               next if ($d->{TYPE} ne "FUNCTION");
+       foreach my $fn (@{$interface->{FUNCTIONS}}) {
+               next if not defined($fn->{OPNUM});
 
-               pidl "\tcase $count: {\n";
-               pidl "\t\tstruct $d->{NAME} *r2 = r;\n";
+               pidl "\tcase $fn->{OPNUM}: {\n";
+               pidl "\t\tstruct $fn->{NAME} *r2 = r;\n";
                pidl "\t\tif (DEBUGLEVEL > 10) {\n";
-               pidl "\t\t\tNDR_PRINT_FUNCTION_DEBUG($d->{NAME}, NDR_IN, r2);\n";
+               pidl "\t\t\tNDR_PRINT_FUNCTION_DEBUG($fn->{NAME}, NDR_IN, r2);\n";
                pidl "\t\t}\n";
-               if ($d->{RETURN_TYPE} && $d->{RETURN_TYPE} ne "void") {
-                       pidl "\t\tr2->out.result = $d->{NAME}(dce_call, mem_ctx, r2);\n";
+               if ($fn->{RETURN_TYPE} && $fn->{RETURN_TYPE} ne "void") {
+                       pidl "\t\tr2->out.result = $fn->{NAME}(dce_call, mem_ctx, r2);\n";
                } else {
-                       pidl "\t\t$d->{NAME}(dce_call, mem_ctx, r2);\n";
+                       pidl "\t\t$fn->{NAME}(dce_call, mem_ctx, r2);\n";
                }
                pidl "\t\tif (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {\n";
-               pidl "\t\t\tDEBUG(5,(\"function $d->{NAME} will reply async\\n\"));\n";
+               pidl "\t\t\tDEBUG(5,(\"function $fn->{NAME} will reply async\\n\"));\n";
                pidl "\t\t}\n";
                pidl "\t\tbreak;\n\t}\n";
-               $count++; 
        }
 }
 
@@ -48,25 +46,23 @@ sub gen_dispatch_switch($)
 # generate the switch statement for function reply
 sub gen_reply_switch($)
 {
-       my $data = shift;
+       my $interface = shift;
 
-       my $count = 0;
-       foreach my $d (@{$data}) {
-               next if ($d->{TYPE} ne "FUNCTION");
+       foreach my $fn (@{$interface->{FUNCTIONS}}) {
+               next if not defined($fn->{OPNUM});
 
-               pidl "\tcase $count: {\n";
-               pidl "\t\tstruct $d->{NAME} *r2 = r;\n";
+               pidl "\tcase $fn->{OPNUM}: {\n";
+               pidl "\t\tstruct $fn->{NAME} *r2 = r;\n";
                pidl "\t\tif (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {\n";
-               pidl "\t\t\tDEBUG(5,(\"function $d->{NAME} replied async\\n\"));\n";
+               pidl "\t\t\tDEBUG(5,(\"function $fn->{NAME} replied async\\n\"));\n";
                pidl "\t\t}\n";
                pidl "\t\tif (DEBUGLEVEL > 10 && dce_call->fault_code == 0) {\n";
-               pidl "\t\t\tNDR_PRINT_FUNCTION_DEBUG($d->{NAME}, NDR_OUT | NDR_SET_VALUES, r2);\n";
+               pidl "\t\t\tNDR_PRINT_FUNCTION_DEBUG($fn->{NAME}, NDR_OUT | NDR_SET_VALUES, r2);\n";
                pidl "\t\t}\n";
                pidl "\t\tif (dce_call->fault_code != 0) {\n";
-               pidl "\t\t\tDEBUG(2,(\"dcerpc_fault %s in $d->{NAME}\\n\", dcerpc_errstr(mem_ctx, dce_call->fault_code)));\n";
+               pidl "\t\t\tDEBUG(2,(\"dcerpc_fault %s in $fn->{NAME}\\n\", dcerpc_errstr(mem_ctx, dce_call->fault_code)));\n";
                pidl "\t\t}\n";
                pidl "\t\tbreak;\n\t}\n";
-               $count++; 
        }
 }
 
@@ -75,8 +71,7 @@ sub gen_reply_switch($)
 sub Boilerplate_Iface($)
 {
        my($interface) = shift;
-       my($data) = $interface->{DATA};
-       my $name = $interface->{NAME};
+       my $name = $interface->{NAME}; 
        my $uname = uc $name;
        my $uuid = util::make_str($interface->{PROPERTIES}->{uuid});
        my $if_version = $interface->{PROPERTIES}->{version};
@@ -133,7 +128,7 @@ static NTSTATUS $name\__op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_C
 
        switch (opnum) {
 ";
-       gen_dispatch_switch($data);
+       gen_dispatch_switch($interface);
 
 pidl "
        default:
@@ -156,7 +151,7 @@ static NTSTATUS $name\__op_reply(struct dcesrv_call_state *dce_call, TALLOC_CTX
 
        switch (opnum) {
 ";
-       gen_reply_switch($data);
+       gen_reply_switch($interface);
 
 pidl "
        default:
@@ -283,11 +278,8 @@ NTSTATUS dcerpc_server_$name\_init(void)
 sub ParseInterface($)
 {
        my($interface) = shift;
-       my($data) = $interface->{DATA};
        my $count = 0;
 
-       $res = "";
-
        if (!defined $interface->{PROPERTIES}->{uuid}) {
                return $res;
        }
@@ -296,19 +288,35 @@ sub ParseInterface($)
                $interface->{PROPERTIES}->{version} = "0.0";
        }
 
-       foreach my $d (@{$data}) {
-               if ($d->{TYPE} eq "FUNCTION") { $count++; }
+       foreach my $fn (@{$interface->{FUNCTIONS}}) {
+               if (defined($fn->{OPNUM})) { $count++; }
        }
 
        if ($count == 0) {
                return $res;
        }
 
-       $res = "/* dcerpc server boilerplate generated by pidl */\n\n";
+       $res .= "/* $interface->{NAME} - dcerpc server boilerplate generated by pidl */\n\n";
        Boilerplate_Iface($interface);
        Boilerplate_Ep_Server($interface);
 
        return $res;
 }
 
+sub Parse($$)
+{
+       my($ndr) = shift;
+       my($filename) = shift;
+
+       $res =  "";
+       $res .= "/* server functions auto-generated by pidl */\n";
+       $res .= "\n";
+
+       foreach my $x (@{$ndr}) {
+               ParseInterface($x) if ($x->{TYPE} eq "INTERFACE" and not defined($x->{PROPERTIES}{object}));
+       }
+
+       return $res;
+}
+
 1;
index bb86fcca50a6f7066460fce3869896c0b06c7f36..647a9068784c05580be644f0f0fd1a20160c0a65 100644 (file)
@@ -17,6 +17,13 @@ sub fatal($$)
        die("$pos->{FILE}:$pos->{LINE}:$s\n");
 }
 
+sub nonfatal($$)
+{
+       my $pos = shift;
+       my $s = shift;
+       warn ("$pos->{FILE}:$pos->{LINE}:warning:$s\n");
+}
+
 sub el_name($)
 {
        my $e = shift;
@@ -56,6 +63,7 @@ my %property_list = (
 
        # function
        "id"                    => {},# what is that? --metze 
+       "noid"                  => {},
        "in"                    => {},
        "out"                   => {},
 
@@ -251,6 +259,14 @@ sub ValidFunction($)
 
        ValidProperties($fn);
 
+       if (util::has_property($fn, "id")) {
+               nonfatal $fn, "[id()] is not correctly supported yet ($fn->{NAME})";
+       }
+
+       if (util::has_property($fn, "id") and util::has_property($fn, "noid")) {
+               fatal $fn, "function can't have [id()] and [noid] property ($fn->{NAME})";
+       }
+
        foreach my $e (@{$fn->{ELEMENTS}}) {
                $e->{PARENT} = $fn;
                if (util::has_property($e, "ref") && !$e->{POINTERS}) {