#!/usr/bin/perl -w
###################################################
-# package to parse IDL files and generate code for
+# package to parse IDL files and generate code for
# rpc functions in Samba
-# Copyright tridge@samba.org 2000
+# Copyright tridge@samba.org 2000-2003
# released under the GNU GPL
use strict;
use lib "$RealBin";
use lib "$RealBin/lib";
use Getopt::Long;
+use File::Basename;
use idl;
use dump;
use header;
+use server;
use parser;
use eparser;
-use client;
+use validator;
use util;
+use template;
my($opt_help) = 0;
my($opt_parse) = 0;
my($opt_dump) = 0;
my($opt_diff) = 0;
my($opt_header) = 0;
+my($opt_template) = 0;
+my($opt_server) = 0;
my($opt_parser) = 0;
my($opt_eparser) = 0;
-my($opt_client);
my($opt_keep) = 0;
my($opt_output);
+my $idl_parser = new idl;
+
#####################################################################
# parse an IDL file returning a structure containing all the data
sub IdlParse($)
{
- # this autoaction allows us to handle simple nodes without an action
-# $::RD_TRACE = 1;
- $::RD_AUTOACTION = q {
- $#item==1 && ref($item[1]) eq "" ?
- $item[1] :
- "XX_" . $item[0] . "_XX[$#item]" };
- my($filename) = shift;
- my($parser) = idl->new;
- my($saved_sep) = $/;
-
- undef $/;
- my($idl) = $parser->idl(`cpp $filename | grep -v '^#'`);
- $/ = $saved_sep;
+ my $filename = shift;
+ my $idl = $idl_parser->parse_idl($filename);
util::CleanData($idl);
return $idl;
}
--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
- --client FILENAME create client calls in FILENAME
--diff run diff on the idl and dumped output
--keep keep the .pidl file
\n";
'parse' => \$opt_parse,
'dump' => \$opt_dump,
'header' => \$opt_header,
+ 'server' => \$opt_server,
+ 'template' => \$opt_template,
'parser' => \$opt_parser,
'eparser' => \$opt_eparser,
- 'client=s' => \$opt_client,
'diff' => \$opt_diff,
'keep' => \$opt_keep
);
exit(0);
}
-my($idl_file) = shift;
-die "ERROR: You must specify an idl file to process" unless ($idl_file);
-
-if (!defined($opt_output)) {
- $opt_output = $idl_file;
-}
-
-my($pidl_file) = util::ChangeExtension($opt_output, "pidl");
-
-if ($opt_parse) {
- print "Generating $pidl_file from $idl_file\n";
- my($idl) = IdlParse($idl_file);
- defined $idl || die "Failed to parse $idl_file";
- util::SaveStructure($pidl_file, $idl) || die "Failed to save $pidl_file";
-}
-
-if ($opt_dump) {
- my($idl) = util::LoadStructure($pidl_file);
- print IdlDump::Dump($idl);
-}
-
-if ($opt_header) {
- my($idl) = util::LoadStructure($pidl_file);
- my($header) = util::ChangeExtension($opt_output, "h");
- print "Generating $header\n";
- util::FileSave($header, IdlHeader::Parse($idl));
-}
-
-if ($opt_parser) {
- my($idl) = util::LoadStructure($pidl_file);
- my($parser) = util::ChangeExtension($opt_output, "c");
- print "Generating $parser\n";
- IdlParser::Parse($idl, $parser);
-}
-
-if ($opt_eparser) {
- my($idl) = util::LoadStructure($pidl_file);
- my($parser) = util::ChangeExtension($opt_output, "c");
- print "Generating $parser for ethereal\n";
- util::FileSave($parser, IdlEParser::Parse($idl));
-}
-
-if ($opt_client) {
- my($idl) = util::LoadStructure($pidl_file);
- my($client) = util::ChangeExtension($opt_client, "c");
- print "Generating $client client calls\n";
- util::FileSave($client, IdlClient::Parse($idl));
+sub process_file($)
+{
+ my $idl_file = shift;
+ my $output;
+ my $pidl;
+
+ my $basename = basename($idl_file, ".idl");
+
+ if (!defined($opt_output)) {
+ $output = $idl_file;
+ } else {
+ $output = $opt_output . $basename;
+ }
+
+ my($pidl_file) = util::ChangeExtension($output, ".pidl");
+
+ print "Compiling $idl_file\n";
+
+ if ($opt_parse) {
+ $pidl = IdlParse($idl_file);
+ defined $pidl || die "Failed to parse $idl_file";
+ IdlValidator::Validate($pidl);
+ if ($opt_keep && !util::SaveStructure($pidl_file, $pidl)) {
+ die "Failed to save $pidl_file\n";
+ }
+ } else {
+ $pidl = util::LoadStructure($pidl_file);
+ defined $pidl || die "Failed to load $pidl_file - maybe you need --parse\n";
+ }
+
+ if ($opt_dump) {
+ print IdlDump::Dump($pidl);
+ }
+
+ if ($opt_header) {
+ my($header) = util::ChangeExtension($output, ".h");
+ util::FileSave($header, IdlHeader::Parse($pidl));
+ }
+
+ if ($opt_server) {
+ my($server) = util::ChangeExtension($output, "_s.c");
+ util::FileSave($server, IdlServer::Parse($pidl));
+ }
+
+ if ($opt_parser) {
+ my($parser) = util::ChangeExtension($output, ".c");
+ IdlParser::Parse($pidl, $parser);
+ }
+
+ if ($opt_eparser) {
+ my($parser) = dirname($output) . "/packet-dcerpc-$basename.c";
+ IdlEParser::Parse($pidl, $parser);
+ }
+
+ 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_template) {
+ print IdlTemplate::Parse($pidl);
+ }
}
-if ($opt_diff) {
- my($idl) = util::LoadStructure($pidl_file);
- my($tempfile) = util::ChangeExtension($opt_output, "tmp");
- util::FileSave($tempfile, IdlDump::Dump($idl));
- system("diff -wu $idl_file $tempfile");
- unlink($tempfile);
-}
-if (!$opt_keep) {
- system("rm -f $pidl_file");
+foreach my $filename (@ARGV) {
+ process_file($filename);
}