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";
38 my($opt_template) = 0;
45 my($opt_dcom_proxy) = 0;
46 my($opt_com_header) = 0;
50 my $idl_parser = new idl;
52 #####################################################################
53 # parse an IDL file returning a structure containing all the data
57 my $idl = $idl_parser->parse_idl($filename);
58 util::CleanData($idl);
63 #########################################
68 perl IDL parser and code generator
69 Copyright (C) tridge\@samba.org
71 Usage: pidl.pl [options] <idlfile>
75 --output OUTNAME put output in OUTNAME.*
76 --parse parse a idl file to a .pidl file
77 --dump dump a pidl file back to idl
78 --header create a C NDR header file
79 --parser create a C NDR parser
80 --client create a C NDR client
81 --server create server boilerplate
82 --template print a template for a pipe
83 --eparser create an ethereal parser
84 --swig create swig wrapper file
85 --diff run diff on the idl and dumped output
86 --keep keep the .pidl file
87 --odl accept ODL input
88 --dcom-proxy create DCOM proxy (implies --odl)
89 --com-header create header for COM interfaces (implies --odl)
96 'help|h|?' => \$opt_help,
97 'output=s' => \$opt_output,
98 'parse' => \$opt_parse,
100 'header' => \$opt_header,
101 'server' => \$opt_server,
102 'template' => \$opt_template,
103 'parser' => \$opt_parser,
104 'client' => \$opt_client,
105 'eparser' => \$opt_eparser,
106 'diff' => \$opt_diff,
108 'keep' => \$opt_keep,
109 'swig' => \$opt_swig,
110 'dcom-proxy' => \$opt_dcom_proxy,
111 'com-header' => \$opt_com_header
121 my $idl_file = shift;
125 my $basename = basename($idl_file, ".idl");
127 if (!defined($opt_output)) {
130 $output = $opt_output . $basename;
133 my($pidl_file) = util::ChangeExtension($output, ".pidl");
135 print "Compiling $idl_file\n";
138 $pidl = IdlParse($idl_file);
139 defined @$pidl || die "Failed to parse $idl_file";
140 typelist::LoadIdl($pidl);
141 IdlValidator::Validate($pidl);
142 if ($opt_keep && !util::SaveStructure($pidl_file, $pidl)) {
143 die "Failed to save $pidl_file\n";
146 $pidl = util::LoadStructure($pidl_file);
147 defined $pidl || die "Failed to load $pidl_file - maybe you need --parse\n";
151 print IdlDump::Dump($pidl);
155 my($tempfile) = util::ChangeExtension($output, ".tmp");
156 util::FileSave($tempfile, IdlDump::Dump($pidl));
157 system("diff -wu $idl_file $tempfile");
161 if ($opt_com_header) {
162 my $res = COMHeader::Parse($pidl);
164 my $h_filename = dirname($output) . "/com_$basename.h";
165 util::FileSave($h_filename,
166 "#include \"librpc/gen_ndr/ndr_orpc.h\"\n" .
167 "#include \"librpc/gen_ndr/ndr_$basename.h\"\n" .
173 if ($opt_dcom_proxy) {
174 my $res = DCOMProxy::Parse($pidl);
176 my ($client) = util::ChangeExtension($output, "_p.c");
177 util::FileSave($client,
178 "#include \"includes.h\"\n" .
179 "#include \"librpc/gen_ndr/com_$basename.h\"\n" .
180 "#include \"lib/com/dcom/dcom.h\"\n" .$res);
186 $pidl = ODL::ODL2IDL($pidl);
190 my($header) = util::ChangeExtension($output, ".h");
191 util::FileSave($header, NdrHeader::Parse($pidl));
193 my($eparserhdr) = dirname($output) . "/packet-dcerpc-$basename.h";
194 IdlEParser::RewriteHeader($pidl, $header, $eparserhdr);
197 my($filename) = $output;
198 $filename =~ s/\/ndr_/\//;
199 $filename = util::ChangeExtension($filename, ".i");
200 IdlSwig::RewriteHeader($pidl, $header, $filename);
205 my ($client) = util::ChangeExtension($output, "_c.c");
207 my $h_filename = util::ChangeExtension($output, ".h");
209 $res .= "#include \"includes.h\"\n";
210 $res .= "#include \"$h_filename\"\n\n";
212 foreach my $x (@{$pidl}) {
213 $res .= NdrClient::ParseInterface($x);
216 util::FileSave($client, $res);
220 my $h_filename = util::ChangeExtension($output, ".h");
224 foreach my $x (@{$pidl}) {
225 next if ($x->{TYPE} ne "INTERFACE");
227 if (util::has_property($x, "object")) {
228 $dcom .= DCOMStub::ParseInterface($x);
230 $plain .= IdlServer::ParseInterface($x);
235 util::FileSave(util::ChangeExtension($output, "_s.c"), $plain);
240 #include \"includes.h\"
241 #include \"$h_filename\"
242 #include \"rpc_server/dcerpc_server.h\"
243 #include \"rpc_server/common/common.h\"
247 util::FileSave(util::ChangeExtension($output, "_d.c"), $dcom);
252 my($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);
266 foreach my $filename (@ARGV) {
267 process_file($filename);