From 2a20e42c2637a6d53d74f3c68a4f420f8cb77a27 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 30 May 2005 09:07:21 +0000 Subject: 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) --- source4/build/pidl/ndr.pm | 11 +++-- source4/build/pidl/ndr_client.pm | 44 ++++++++++++++++---- source4/build/pidl/ndr_header.pm | 90 +++++++++++++++++++++------------------- source4/build/pidl/ndr_parser.pm | 3 ++ source4/build/pidl/pidl.pl | 17 +------- source4/build/pidl/server.pm | 74 ++++++++++++++++++--------------- source4/build/pidl/validator.pm | 16 +++++++ 7 files changed, 153 insertions(+), 102 deletions(-) (limited to 'source4') 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}) { -- cgit