3 ###################################################
4 # package to parse IDL files and generate code for
5 # rpc functions in Samba
6 # Copyright tridge@samba.org 2000-2003
7 # released under the GNU GPL
11 use FindBin
qw($RealBin);
13 use lib "$RealBin/lib";
35 my($opt_template) = 0;
44 my $idl_parser = new idl;
46 #####################################################################
47 # parse an IDL file returning a structure containing all the data
51 my $idl = $idl_parser->parse_idl($filename);
52 util::CleanData($idl);
57 #########################################
62 perl IDL parser and code generator
63 Copyright (C) tridge\@samba.org
65 Usage: pidl.pl [options] <idlfile>
69 --output OUTNAME put output in OUTNAME.*
70 --parse parse a idl file to a .pidl file
71 --dump dump a pidl file back to idl
72 --header create a C header file
73 --parser create a C parser
74 --client create a C client
75 --server create server boilerplate
76 --template print a template for a pipe
77 --eparser create an ethereal parser
78 --swig create swig wrapper file
79 --diff run diff on the idl and dumped output
80 --keep keep the .pidl file
87 'help|h|?' => \$opt_help,
88 'output=s' => \$opt_output,
89 'parse' => \$opt_parse,
91 'header' => \$opt_header,
92 'server' => \$opt_server,
93 'template' => \$opt_template,
94 'parser' => \$opt_parser,
95 'client' => \$opt_client,
96 'eparser' => \$opt_eparser,
109 my $idl_file = shift;
113 my $basename = basename($idl_file, ".idl");
115 if (!defined($opt_output)) {
118 $output = $opt_output . $basename;
121 my($pidl_file) = util::ChangeExtension($output, ".pidl");
123 print "Compiling $idl_file\n";
126 $pidl = IdlParse($idl_file);
127 defined @$pidl || die "Failed to parse $idl_file";
128 IdlValidator::Validate($pidl);
129 if ($opt_keep && !util::SaveStructure($pidl_file, $pidl)) {
130 die "Failed to save $pidl_file\n";
133 $pidl = util::LoadStructure($pidl_file);
134 defined $pidl || die "Failed to load $pidl_file - maybe you need --parse\n";
138 print IdlDump::Dump($pidl);
142 my($header) = util::ChangeExtension($output, ".h");
143 util::FileSave($header, IdlHeader::Parse($pidl));
147 my ($client) = util::ChangeExtension($output, "_c.c");
149 my $h_filename = util::ChangeExtension($output, ".h");
150 my $need_dcom_register = 0;
152 $res .= "#include \"includes.h\"\n";
153 $res .= "#include \"$h_filename\"\n\n";
155 foreach my $x (@{$pidl}) {
156 if (util::has_property($x, "object")) {
157 $res .= IdlProxy::ParseInterface($x);
158 $need_dcom_register = 1;
160 $res .= IdlClient::ParseInterface($x);
164 if ($need_dcom_register) {
165 $res .= IdlProxy::RegistrationFunction($pidl, $basename);
167 util::FileSave($client, $res);
171 my $h_filename = util::ChangeExtension($output, ".h");
175 foreach my $x (@{$pidl}) {
176 next if ($x->{TYPE} ne "INTERFACE");
178 if (util::has_property($x, "object")) {
179 $dcom .= IdlStub::ParseInterface($x);
181 $plain .= IdlServer::ParseInterface($x);
186 util::FileSave(util::ChangeExtension($output, "_s.c"), $plain);
191 #include \"includes.h\"
192 #include \"$h_filename\"
193 #include \"rpc_server/dcerpc_server.h\"
194 #include \"rpc_server/common/common.h\"
198 util::FileSave(util::ChangeExtension($output, "_d.c"), $dcom);
203 my($parser) = util::ChangeExtension($output, ".c");
204 IdlParser::Parse($pidl, $parser);
209 # Generate regular .c and .h files for marshaling and
212 my($parser) = util::ChangeExtension($output, ".c");
213 IdlParser::Parse($pidl, $parser);
215 my($header) = util::ChangeExtension($output, ".h");
216 util::FileSave($header, IdlHeader::Parse($pidl));
218 # Postprocess to produce ethereal parsers.
220 my($eparser) = dirname($output) . "/packet-dcerpc-$basename.c";
221 IdlEParser::RewriteC($pidl, $parser, $eparser);
223 my($eparserhdr) = dirname($output) . "/packet-dcerpc-$basename.h";
224 IdlEParser::RewriteHeader($pidl, $header, $eparserhdr);
228 my($filename) = $output;
229 $filename =~ s/\/ndr_/\//;
230 $filename = util::ChangeExtension($filename, ".i");
231 util::FileSave($filename, IdlSwig::Parse($pidl));
235 my($tempfile) = util::ChangeExtension($output, ".tmp");
236 util::FileSave($tempfile, IdlDump::Dump($pidl));
237 system("diff -wu $idl_file $tempfile");
242 print IdlTemplate::Parse($pidl);
247 foreach my $filename (@ARGV) {
248 process_file($filename);