3 ###################################################
4 # package to parse IDL files and generate code for
5 # rpc functions in Samba
6 # Copyright tridge@samba.org 2000-2003
7 # Copyright jelmer@samba.org 2005
8 # released under the GNU GPL
12 use FindBin qw($RealBin);
14 use lib "$RealBin/lib";
39 my($opt_template) = 0;
46 my($opt_dcom_proxy) = 0;
47 my($opt_com_header) = 0;
52 my $idl_parser = new idl;
54 #########################################
59 perl IDL parser and code generator
60 Copyright (C) tridge\@samba.org
62 Usage: pidl.pl [options] <idlfile>
66 --output=OUTNAME put output in OUTNAME.*
67 --parse parse a idl file to a .pidl file
68 --dump dump a pidl file back to idl
69 --header[=OUTFILE] create a C NDR header file
70 --parser[=OUTFILE] create a C NDR parser
71 --client create a C NDR client
72 --server create server boilerplate
73 --template print a template for a pipe
74 --eparser create an ethereal parser
75 --swig create swig wrapper file
76 --diff run diff on the idl and dumped output
77 --keep keep the .pidl file
78 --odl accept ODL input
79 --dcom-proxy create DCOM proxy (implies --odl)
80 --com-header create header for COM interfaces (implies --odl)
88 'help|h|?' => \$opt_help,
89 'output=s' => \$opt_output,
90 'parse' => \$opt_parse,
92 'header:s' => \$opt_header,
93 'server' => \$opt_server,
94 'template' => \$opt_template,
95 'parser:s' => \$opt_parser,
96 'client' => \$opt_client,
97 'eparser' => \$opt_eparser,
100 'keep' => \$opt_keep,
101 'swig' => \$opt_swig,
102 'dcom-proxy' => \$opt_dcom_proxy,
103 'com-header' => \$opt_com_header,
104 'quiet' => \$opt_quiet
114 my $idl_file = shift;
118 my $basename = basename($idl_file, ".idl");
120 if (!defined($opt_output)) {
123 $output = $opt_output . $basename;
126 my($pidl_file) = util::ChangeExtension($output, ".pidl");
128 unless ($opt_quiet) { print "Compiling $idl_file\n"; }
131 $pidl = $idl_parser->parse_idl($idl_file);
132 defined @$pidl || die "Failed to parse $idl_file";
133 typelist::LoadIdl($pidl);
134 IdlValidator::Validate($pidl);
135 if ($opt_keep && !util::SaveStructure($pidl_file, $pidl)) {
136 die "Failed to save $pidl_file\n";
139 $pidl = util::LoadStructure($pidl_file);
140 defined $pidl || die "Failed to load $pidl_file - maybe you need --parse\n";
144 print IdlDump::Dump($pidl);
148 my($tempfile) = util::ChangeExtension($output, ".tmp");
149 util::FileSave($tempfile, IdlDump::Dump($pidl));
150 system("diff -wu $idl_file $tempfile");
154 if ($opt_com_header) {
155 my $res = COMHeader::Parse($pidl);
157 my $h_filename = dirname($output) . "/com_$basename.h";
158 util::FileSave($h_filename,
159 "#include \"librpc/gen_ndr/ndr_orpc.h\"\n" .
160 "#include \"librpc/gen_ndr/ndr_$basename.h\"\n" .
166 if ($opt_dcom_proxy) {
167 my $res = DCOMProxy::Parse($pidl);
169 my ($client) = util::ChangeExtension($output, "_p.c");
170 util::FileSave($client,
171 "#include \"includes.h\"\n" .
172 "#include \"librpc/gen_ndr/com_$basename.h\"\n" .
173 "#include \"lib/com/dcom/dcom.h\"\n" .$res);
179 $pidl = ODL::ODL2IDL($pidl);
182 if (defined($opt_header)) {
183 my $header = $opt_header;
185 $header = util::ChangeExtension($output, ".h");
188 util::FileSave($header, NdrHeader::Parse($pidl));
190 my($eparserhdr) = dirname($output) . "/packet-dcerpc-$basename.h";
191 IdlEParser::RewriteHeader($pidl, $header, $eparserhdr);
194 my($filename) = $output;
195 $filename =~ s/\/ndr_/\//;
196 $filename = util::ChangeExtension($filename, ".i");
197 IdlSwig::RewriteHeader($pidl, $header, $filename);
202 my ($client) = util::ChangeExtension($output, "_c.c");
204 my $h_filename = util::ChangeExtension($output, ".h");
206 $res .= "#include \"includes.h\"\n";
207 $res .= "#include \"$h_filename\"\n\n";
209 foreach my $x (@{$pidl}) {
210 $res .= NdrClient::ParseInterface($x);
213 util::FileSave($client, $res);
217 my $h_filename = util::ChangeExtension($output, ".h");
221 foreach my $x (@{$pidl}) {
222 next if ($x->{TYPE} ne "INTERFACE");
224 if (util::has_property($x, "object")) {
225 $dcom .= DCOMStub::ParseInterface($x);
227 $plain .= IdlServer::ParseInterface($x);
232 util::FileSave(util::ChangeExtension($output, "_s.c"), $plain);
237 #include \"includes.h\"
238 #include \"$h_filename\"
239 #include \"rpc_server/dcerpc_server.h\"
240 #include \"rpc_server/common/common.h\"
244 util::FileSave(util::ChangeExtension($output, "_d.c"), $dcom);
248 if (defined($opt_parser)) {
249 my $parser = $opt_parser;
251 $parser = util::ChangeExtension($output, ".c");
253 util::FileSave($parser, NdrParser::Parse($pidl, $parser));
255 my($eparser) = dirname($output) . "/packet-dcerpc-$basename.c";
256 IdlEParser::RewriteC($pidl, $parser, $eparser);
261 print IdlTemplate::Parse($pidl);
265 foreach my $filename (@ARGV) {
266 process_file($filename);