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);
13 use lib "$RealBin/..";
40 my($opt_uint_enums) = 0;
43 my($opt_template) = 0;
58 my($opt_warn_compat) = 0;
60 my $idl_parser = new idl;
62 #########################################
66 print "perl IDL parser and code generator
67 Copyright (C) tridge\@samba.org
69 Usage: pidl [options] <idlfile>
73 --output=OUTNAME put output in OUTNAME.*
74 --parse parse a idl file to a .pidl file
75 --dump dump a pidl file back to idl
76 --uint-enums don't use C enums, instead use uint* types
77 --header[=OUTFILE] create a C NDR header file
78 --parser[=OUTFILE] create a C NDR parser
79 --ejs[=OUTFILE] create ejs wrapper file
80 --client[=OUTFILE] create a C NDR client
81 --server[=OUTFILE] create server boilerplate
82 --template print a template for a pipe
83 --eth-parser[=OUTFILE]create an ethereal parser
84 --eth-header[=OUTFILE]create an ethereal header file
85 --swig[=OUTFILE] create swig wrapper file
86 --diff run diff on the idl and dumped output
87 --keep[=OUTFILE] keep the .pidl file
88 --odl accept ODL input
89 --dcom-proxy[=OUTFILE]create DCOM proxy (implies --odl)
90 --com-header[=OUTFILE]create header for COM interfaces (implies --odl)
91 --warn-compat warn about incompatibility with other compilers
100 'help|h|?' => \$opt_help,
101 'output=s' => \$opt_output,
102 'parse' => \$opt_parse,
103 'dump' => \$opt_dump,
104 'uint-enums' => \$opt_uint_enums,
105 'header:s' => \$opt_header,
106 'server:s' => \$opt_server,
107 'template' => \$opt_template,
108 'parser:s' => \$opt_parser,
109 'client:s' => \$opt_client,
110 'eth-parser:s' => \$opt_eth_parser,
111 'eth-header:s' => \$opt_eth_header,
112 'ejs:s' => \$opt_ejs,
113 'diff' => \$opt_diff,
115 'keep:s' => \$opt_keep,
116 'swig:s' => \$opt_swig,
117 'dcom-proxy:s' => \$opt_dcom_proxy,
118 'com-header:s' => \$opt_com_header,
119 'quiet' => \$opt_quiet,
120 'verbose' => \$opt_verbose,
121 'warn-compat' => \$opt_warn_compat
131 my $idl_file = shift;
136 my $basename = basename($idl_file, ".idl");
138 if (!defined($opt_output)) {
141 $output = $opt_output . $basename;
144 my($pidl_file) = ($opt_keep or util::ChangeExtension($output, ".pidl"));
146 unless ($opt_quiet) { print "Compiling $idl_file\n"; }
149 $pidl = $idl_parser->parse_idl($idl_file);
150 defined @$pidl || die "Failed to parse $idl_file";
151 typelist::LoadIdl($pidl);
152 IdlValidator::Validate($pidl);
153 if (defined($opt_keep) && !util::SaveStructure($pidl_file, $pidl)) {
154 die "Failed to save $pidl_file\n";
157 $pidl = util::LoadStructure($pidl_file);
158 defined $pidl || die "Failed to load $pidl_file - maybe you need --parse\n";
161 if ($opt_uint_enums) {
162 util::setUseUintEnums(1);
166 print IdlDump::Dump($pidl);
170 my($tempfile) = util::ChangeExtension($output, ".tmp");
171 util::FileSave($tempfile, IdlDump::Dump($pidl));
172 system("diff -wu $idl_file $tempfile");
176 if (defined($opt_com_header)) {
177 my $res = COMHeader::Parse($pidl);
179 my $comh_filename = ($opt_com_header or (dirname($output) . "/com_$basename.h"));
180 util::FileSave($comh_filename,
181 "#include \"librpc/gen_ndr/ndr_orpc.h\"\n" .
182 "#include \"librpc/gen_ndr/ndr_$basename.h\"\n" .
188 if (defined($opt_dcom_proxy)) {
189 my $res = DCOMProxy::Parse($pidl);
191 my ($client) = ($opt_dcom_proxy or util::ChangeExtension($output, "_p.c"));
192 util::FileSave($client,
193 "#include \"includes.h\"\n" .
194 "#include \"librpc/gen_ndr/com_$basename.h\"\n" .
195 "#include \"lib/com/dcom/dcom.h\"\n" .$res);
200 if ($opt_warn_compat) {
201 IDLCompat::Check($pidl);
205 $pidl = ODL::ODL2IDL($pidl);
208 if (defined($opt_header) or defined($opt_eth_parser) or
209 defined($opt_eth_header) or defined($opt_client) or
210 defined($opt_server) or defined($opt_parser) or
212 $ndr = Ndr::Parse($pidl);
215 if (defined($opt_header)) {
216 my $header = $opt_header;
218 $header = util::ChangeExtension($output, ".h");
220 util::FileSave($header, NdrHeader::Parse($ndr));
221 if (defined($opt_swig)) {
222 my($filename) = $output;
223 $filename =~ s/\/ndr_/\//;
224 $filename = ($opt_swig or util::ChangeExtension($filename, ".i"));
225 IdlSwig::RewriteHeader($pidl, $header, $filename);
229 if (defined($opt_eth_header)) {
230 my($eparserhdr) = ($opt_eth_header or (dirname($output) . "/packet-dcerpc-$basename.h"));
232 util::FileSave($eparserhdr, EthHeader::Parse($ndr));
235 my $h_filename = util::ChangeExtension($output, ".h");
236 if (defined($opt_client)) {
237 my ($client) = ($opt_client or util::ChangeExtension($output, "_c.c"));
239 util::FileSave($client, NdrClient::Parse($ndr,$h_filename));
242 if (defined($opt_ejs)) {
243 my $ejs = ($opt_ejs or util::ChangeExtension($output, "_ejs.c"));
244 util::FileSave($ejs, EjsClient::Parse($ndr, $h_filename));
246 $ejs = ($opt_ejs or util::ChangeExtension($output, "_ejs.h"));
247 util::FileSave($ejs, EjsHeader::Parse($ndr));
250 if (defined($opt_server)) {
253 foreach my $x (@{$pidl}) {
254 next if ($x->{TYPE} ne "INTERFACE");
256 if (util::has_property($x, "object")) {
257 $dcom .= DCOMStub::ParseInterface($x);
261 util::FileSave(($opt_server or util::ChangeExtension($output, "_s.c")), NdrServer::Parse($ndr,$h_filename));
265 #include \"includes.h\"
266 #include \"$h_filename\"
267 #include \"rpc_server/dcerpc_server.h\"
268 #include \"rpc_server/common/common.h\"
272 util::FileSave(util::ChangeExtension($output, "_d.c"), $dcom);
276 if (defined($opt_parser)) {
277 my $parser = ($opt_parser or util::ChangeExtension($output, ".c"));
279 util::FileSave($parser, NdrParser::Parse($ndr, $parser));
282 if (defined($opt_eth_parser)) {
283 my($eparser) = ($opt_eth_parser or dirname($output) . "/packet-dcerpc-$basename.c");
284 util::FileSave($eparser, EthParser::Parse($ndr, $basename, $eparser));
288 print IdlTemplate::Parse($pidl);
292 foreach my $filename (@ARGV) {
293 process_file($filename);