summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2005-05-30 09:07:21 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:17:16 -0500
commit2a20e42c2637a6d53d74f3c68a4f420f8cb77a27 (patch)
treecec1b76d704f47c085b4a1f645350b0e6848e7f2
parent9ab8ed3bab065afb0ba98277b7e4728b24caabe0 (diff)
downloadsamba-2a20e42c2637a6d53d74f3c68a4f420f8cb77a27.tar.gz
samba-2a20e42c2637a6d53d74f3c68a4f420f8cb77a27.tar.bz2
samba-2a20e42c2637a6d53d74f3c68a4f420f8cb77a27.zip
r7098: - make use of the NDR table instead of the IDL table in the client and server generation
- 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 (This used to be commit 189730d1430e7f728d62dd5dc52f2a90c1a556d7)
-rw-r--r--source4/build/pidl/ndr.pm11
-rw-r--r--source4/build/pidl/ndr_client.pm44
-rw-r--r--source4/build/pidl/ndr_header.pm90
-rw-r--r--source4/build/pidl/ndr_parser.pm3
-rwxr-xr-xsource4/build/pidl/pidl.pl17
-rw-r--r--source4/build/pidl/server.pm74
-rw-r--r--source4/build/pidl/validator.pm16
7 files changed, 153 insertions, 102 deletions
diff --git a/source4/build/pidl/ndr.pm b/source4/build/pidl/ndr.pm
index aa1a557dd1..5fafab3cd0 100644
--- a/source4/build/pidl/ndr.pm
+++ b/source4/build/pidl/ndr.pm
@@ -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") {
diff --git a/source4/build/pidl/ndr_client.pm b/source4/build/pidl/ndr_client.pm
index ca6fc22465..eb7d73b991 100644
--- a/source4/build/pidl/ndr_client.pm
+++ b/source4/build/pidl/ndr_client.pm
@@ -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;
}
diff --git a/source4/build/pidl/ndr_header.pm b/source4/build/pidl/ndr_header.pm
index dfc20389ea..429f603f88 100644
--- a/source4/build/pidl/ndr_header.pm
+++ b/source4/build/pidl/ndr_header.pm
@@ -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";
}
#####################################################################
diff --git a/source4/build/pidl/ndr_parser.pm b/source4/build/pidl/ndr_parser.pm
index a73675159b..edc6df31ad 100644
--- a/source4/build/pidl/ndr_parser.pm
+++ b/source4/build/pidl/ndr_parser.pm
@@ -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 "};";
diff --git a/source4/build/pidl/pidl.pl b/source4/build/pidl/pidl.pl
index 478c7a273a..a1089f90b1 100755
--- a/source4/build/pidl/pidl.pl
+++ b/source4/build/pidl/pidl.pl
@@ -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 = "
diff --git a/source4/build/pidl/server.pm b/source4/build/pidl/server.pm
index 46dada7c7f..29745686fe 100644
--- a/source4/build/pidl/server.pm
+++ b/source4/build/pidl/server.pm
@@ -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;
diff --git a/source4/build/pidl/validator.pm b/source4/build/pidl/validator.pm
index bb86fcca50..647a906878 100644
--- a/source4/build/pidl/validator.pm
+++ b/source4/build/pidl/validator.pm
@@ -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}) {