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);
62 #########################################
67 perl IDL parser and code generator
68 Copyright (C) tridge\@samba.org
70 Usage: pidl.pl [options] <idlfile>
74 --output=OUTNAME put output in OUTNAME.*
75 --parse parse a idl file to a .pidl file
76 --dump dump a pidl file back to idl
77 --header[=OUTFILE] create a C NDR header file
78 --parser[=OUTFILE] create a C NDR parser
79 --client create a C NDR client
80 --server create server boilerplate
81 --template print a template for a pipe
82 --eparser create an ethereal parser
83 --swig create swig wrapper file
84 --diff run diff on the idl and dumped output
85 --keep keep the .pidl file
86 --odl accept ODL input
87 --dcom-proxy create DCOM proxy (implies --odl)
88 --com-header create header for COM interfaces (implies --odl)
95 'help|h|?' => \$opt_help,
96 'output=s' => \$opt_output,
97 'parse' => \$opt_parse,
99 'header:s' => \$opt_header,
100 'server' => \$opt_server,
101 'template' => \$opt_template,
102 'parser:s' => \$opt_parser,
103 'client' => \$opt_client,
104 'eparser' => \$opt_eparser,
105 'diff' => \$opt_diff,
107 'keep' => \$opt_keep,
108 'swig' => \$opt_swig,
109 'dcom-proxy' => \$opt_dcom_proxy,
110 'com-header' => \$opt_com_header
120 my $idl_file = shift;
124 my $basename = basename($idl_file, ".idl");
126 if (!defined($opt_output)) {
129 $output = $opt_output . $basename;
132 my($pidl_file) = util::ChangeExtension($output, ".pidl");
134 print "Compiling $idl_file\n";
137 $pidl = IdlParse($idl_file);
138 defined @$pidl || die "Failed to parse $idl_file";
139 typelist::LoadIdl($pidl);
140 IdlValidator::Validate($pidl);
141 if ($opt_keep && !util::SaveStructure($pidl_file, $pidl)) {
142 die "Failed to save $pidl_file\n";
145 $pidl = util::LoadStructure($pidl_file);
146 defined $pidl || die "Failed to load $pidl_file - maybe you need --parse\n";
150 print IdlDump::Dump($pidl);
154 my($tempfile) = util::ChangeExtension($output, ".tmp");
155 util::FileSave($tempfile, IdlDump::Dump($pidl));
156 system("diff -wu $idl_file $tempfile");
160 if ($opt_com_header) {
161 my $res = COMHeader::Parse($pidl);
163 my $h_filename = dirname($output) . "/com_$basename.h";
164 util::FileSave($h_filename,
165 "#include \"librpc/gen_ndr/ndr_orpc.h\"\n" .
166 "#include \"librpc/gen_ndr/ndr_$basename.h\"\n" .
172 if ($opt_dcom_proxy) {
173 my $res = DCOMProxy::Parse($pidl);
175 my ($client) = util::ChangeExtension($output, "_p.c");
176 util::FileSave($client,
177 "#include \"includes.h\"\n" .
178 "#include \"librpc/gen_ndr/com_$basename.h\"\n" .
179 "#include \"lib/com/dcom/dcom.h\"\n" .$res);
185 $pidl = ODL::ODL2IDL($pidl);
188 if (defined($opt_header)) {
189 my $header = $opt_header;
191 $header = util::ChangeExtension($output, ".h");
194 util::FileSave($header, NdrHeader::Parse($pidl));
196 my($eparserhdr) = dirname($output) . "/packet-dcerpc-$basename.h";
197 IdlEParser::RewriteHeader($pidl, $header, $eparserhdr);
200 my($filename) = $output;
201 $filename =~ s/\/ndr_/\//;
202 $filename = util::ChangeExtension($filename, ".i");
203 IdlSwig::RewriteHeader($pidl, $header, $filename);
208 my ($client) = util::ChangeExtension($output, "_c.c");
210 my $h_filename = util::ChangeExtension($output, ".h");
212 $res .= "#include \"includes.h\"\n";
213 $res .= "#include \"$h_filename\"\n\n";
215 foreach my $x (@{$pidl}) {
216 $res .= NdrClient::ParseInterface($x);
219 util::FileSave($client, $res);
223 my $h_filename = util::ChangeExtension($output, ".h");
227 foreach my $x (@{$pidl}) {
228 next if ($x->{TYPE} ne "INTERFACE");
230 if (util::has_property($x, "object")) {
231 $dcom .= DCOMStub::ParseInterface($x);
233 $plain .= IdlServer::ParseInterface($x);
238 util::FileSave(util::ChangeExtension($output, "_s.c"), $plain);
243 #include \"includes.h\"
244 #include \"$h_filename\"
245 #include \"rpc_server/dcerpc_server.h\"
246 #include \"rpc_server/common/common.h\"
250 util::FileSave(util::ChangeExtension($output, "_d.c"), $dcom);
254 if (defined($opt_parser)) {
255 my $parser = $opt_parser;
257 $parser = util::ChangeExtension($output, ".c");
259 util::FileSave($parser, NdrParser::Parse($pidl, $parser));
261 my($eparser) = dirname($output) . "/packet-dcerpc-$basename.c";
262 IdlEParser::RewriteC($pidl, $parser, $eparser);
267 print IdlTemplate::Parse($pidl);
272 foreach my $filename (@ARGV) {
273 process_file($filename);