use File::Basename;
use idl;
use dump;
-use header;
+use ndr_client;
+use ndr_header;
+use ndr;
use server;
-use parser;
+use dcom_proxy;
+use dcom_stub;
+use com_header;
+use odl;
use eparser;
use validator;
+use typelist;
use util;
use template;
+use swig;
my($opt_help) = 0;
my($opt_parse) = 0;
my($opt_diff) = 0;
my($opt_header) = 0;
my($opt_template) = 0;
+my($opt_client) = 0;
my($opt_server) = 0;
my($opt_parser) = 0;
my($opt_eparser) = 0;
my($opt_keep) = 0;
+my($opt_swig) = 0;
+my($opt_dcom_proxy) = 0;
+my($opt_com_header) = 0;
+my($opt_odl) = 0;
my($opt_output);
my $idl_parser = new idl;
sub ShowHelp()
{
print "
- perl IDL parser and code generator
- Copyright (C) tridge\@samba.org
-
- Usage: pidl.pl [options] <idlfile>
-
- Options:
- --help this help page
- --output OUTNAME put output in OUTNAME.*
- --parse parse a idl file to a .pidl file
- --dump dump a pidl file back to idl
- --header create a C header file
- --parser create a C parser
- --server create server boilerplate
- --template print a template for a pipe
- --eparser create an ethereal parser
- --diff run diff on the idl and dumped output
- --keep keep the .pidl file
- \n";
+ perl IDL parser and code generator
+ Copyright (C) tridge\@samba.org
+
+ Usage: pidl.pl [options] <idlfile>
+
+ Options:
+ --help this help page
+ --output OUTNAME put output in OUTNAME.*
+ --parse parse a idl file to a .pidl file
+ --dump dump a pidl file back to idl
+ --header create a C NDR header file
+ --parser create a C NDR parser
+ --client create a C NDR client
+ --server create server boilerplate
+ --template print a template for a pipe
+ --eparser create an ethereal parser
+ --swig create swig wrapper file
+ --diff run diff on the idl and dumped output
+ --keep keep the .pidl file
+ --odl accept ODL input
+ --dcom-proxy create DCOM proxy (implies --odl)
+ --com-header create header for COM interfaces (implies --odl)
+ \n";
exit(0);
}
'server' => \$opt_server,
'template' => \$opt_template,
'parser' => \$opt_parser,
+ 'client' => \$opt_client,
'eparser' => \$opt_eparser,
'diff' => \$opt_diff,
- 'keep' => \$opt_keep
+ 'odl' => \$opt_odl,
+ 'keep' => \$opt_keep,
+ 'swig' => \$opt_swig,
+ 'dcom-proxy' => \$opt_dcom_proxy,
+ 'com-header' => \$opt_com_header
);
if ($opt_help) {
if ($opt_parse) {
$pidl = IdlParse($idl_file);
- defined $pidl || die "Failed to parse $idl_file";
-# IdlValidator::Validate($pidl);
+ defined @$pidl || die "Failed to parse $idl_file";
+ typelist::LoadIdl($pidl);
+ IdlValidator::Validate($pidl);
if ($opt_keep && !util::SaveStructure($pidl_file, $pidl)) {
die "Failed to save $pidl_file\n";
}
print IdlDump::Dump($pidl);
}
+ if ($opt_diff) {
+ my($tempfile) = util::ChangeExtension($output, ".tmp");
+ util::FileSave($tempfile, IdlDump::Dump($pidl));
+ system("diff -wu $idl_file $tempfile");
+ unlink($tempfile);
+ }
+
+ if ($opt_com_header) {
+ my $res = COMHeader::Parse($pidl);
+ if ($res) {
+ my $h_filename = dirname($output) . "/com_$basename.h";
+ util::FileSave($h_filename,
+ "#include \"librpc/gen_ndr/ndr_orpc.h\"\n" .
+ "#include \"librpc/gen_ndr/ndr_$basename.h\"\n" .
+ $res);
+ }
+ $opt_odl = 1;
+ }
+
+ if ($opt_dcom_proxy) {
+ my $res = DCOMProxy::Parse($pidl);
+ if ($res) {
+ my ($client) = util::ChangeExtension($output, "_p.c");
+ util::FileSave($client,
+ "#include \"includes.h\"\n" .
+ "#include \"librpc/gen_ndr/com_$basename.h\"\n" .
+ "#include \"lib/dcom/common/orpc.h\"\n". $res);
+ }
+ $opt_odl = 1;
+ }
+
+ if ($opt_odl) {
+ $pidl = ODL::ODL2IDL($pidl);
+ }
+
if ($opt_header) {
my($header) = util::ChangeExtension($output, ".h");
- util::FileSave($header, IdlHeader::Parse($pidl));
+ util::FileSave($header, NdrHeader::Parse($pidl));
+ if ($opt_eparser) {
+ my($eparserhdr) = dirname($output) . "/packet-dcerpc-$basename.h";
+ IdlEParser::RewriteHeader($pidl, $header, $eparserhdr);
+ }
+ if ($opt_swig) {
+ my($filename) = $output;
+ $filename =~ s/\/ndr_/\//;
+ $filename = util::ChangeExtension($filename, ".i");
+ IdlSwig::RewriteHeader($pidl, $header, $filename);
+ }
}
- if ($opt_server) {
- my($server) = util::ChangeExtension($output, "_s.c");
- util::FileSave($server, IdlServer::Parse($pidl));
- }
+ if ($opt_client) {
+ my ($client) = util::ChangeExtension($output, "_c.c");
+ my $res = "";
+ my $h_filename = util::ChangeExtension($output, ".h");
- if ($opt_parser) {
- my($parser) = util::ChangeExtension($output, ".c");
- IdlParser::Parse($pidl, $parser);
+ $res .= "#include \"includes.h\"\n";
+ $res .= "#include \"$h_filename\"\n\n";
+
+ foreach my $x (@{$pidl}) {
+ $res .= NdrClient::ParseInterface($x);
+ }
+
+ util::FileSave($client, $res);
}
- if ($opt_eparser) {
- my($parser) = dirname($output) . "/packet-dcerpc-$basename.c";
- IdlEParser::Parse($pidl, $parser);
- $parser = dirname($output) . "/packet-dcerpc-proto-$basename.h";
- IdlEParser::ParseHeader($pidl, $parser);
- my($header) = dirname($output) . "/packet-dcerpc-proto.h";
- open(OUT, ">>$header") || die "can't open $header";
- print OUT "#include \"packet-dcerpc-proto-$basename.h\"\n";
- close(OUT);
+ if ($opt_server) {
+ my $h_filename = util::ChangeExtension($output, ".h");
+ my $plain = "";
+ my $dcom = "";
+
+ foreach my $x (@{$pidl}) {
+ next if ($x->{TYPE} ne "INTERFACE");
+
+ 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);
+ }
+
+ if ($dcom ne "") {
+ $dcom = "
+#include \"includes.h\"
+#include \"$h_filename\"
+#include \"rpc_server/dcerpc_server.h\"
+#include \"rpc_server/common/common.h\"
+
+$dcom
+";
+ util::FileSave(util::ChangeExtension($output, "_d.c"), $dcom);
+ }
}
- if ($opt_diff) {
- my($tempfile) = util::ChangeExtension($output, ".tmp");
- util::FileSave($tempfile, IdlDump::Dump($pidl));
- system("diff -wu $idl_file $tempfile");
- unlink($tempfile);
+ if ($opt_parser) {
+ my($parser) = util::ChangeExtension($output, ".c");
+ util::FileSave($parser, NdrParser::Parse($pidl, $parser));
+ if($opt_eparser) {
+ my($eparser) = dirname($output) . "/packet-dcerpc-$basename.c";
+ IdlEParser::RewriteC($pidl, $parser, $eparser);
+ }
}
if ($opt_template) {