r4549: got rid of a lot more uses of plain talloc(), instead using
[Samba/gebeck_regimport.git] / source4 / build / pidl / pidl.pl
blob6d0ff6908193d85b4f1162afc40c97607b3f84b3
1 #!/usr/bin/perl -w
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
9 use strict;
11 use FindBin qw($RealBin);
12 use lib "$RealBin";
13 use lib "$RealBin/lib";
14 use Getopt::Long;
15 use File::Basename;
16 use idl;
17 use dump;
18 use header;
19 use server;
20 use client;
21 use proxy;
22 use stub;
23 use parser;
24 use eparser;
25 use validator;
26 use util;
27 use template;
28 use swig;
30 my($opt_help) = 0;
31 my($opt_parse) = 0;
32 my($opt_dump) = 0;
33 my($opt_diff) = 0;
34 my($opt_header) = 0;
35 my($opt_template) = 0;
36 my($opt_client) = 0;
37 my($opt_server) = 0;
38 my($opt_parser) = 0;
39 my($opt_eparser) = 0;
40 my($opt_keep) = 0;
41 my($opt_swig) = 0;
42 my($opt_output);
44 my $idl_parser = new idl;
46 #####################################################################
47 # parse an IDL file returning a structure containing all the data
48 sub IdlParse($)
50 my $filename = shift;
51 my $idl = $idl_parser->parse_idl($filename);
52 util::CleanData($idl);
53 return $idl;
57 #########################################
58 # display help text
59 sub ShowHelp()
61 print "
62 perl IDL parser and code generator
63 Copyright (C) tridge\@samba.org
65 Usage: pidl.pl [options] <idlfile>
67 Options:
68 --help this help page
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
81 \n";
82 exit(0);
85 # main program
86 GetOptions (
87 'help|h|?' => \$opt_help,
88 'output=s' => \$opt_output,
89 'parse' => \$opt_parse,
90 'dump' => \$opt_dump,
91 'header' => \$opt_header,
92 'server' => \$opt_server,
93 'template' => \$opt_template,
94 'parser' => \$opt_parser,
95 'client' => \$opt_client,
96 'eparser' => \$opt_eparser,
97 'diff' => \$opt_diff,
98 'keep' => \$opt_keep,
99 'swig' => \$opt_swig
102 if ($opt_help) {
103 ShowHelp();
104 exit(0);
107 sub process_file($)
109 my $idl_file = shift;
110 my $output;
111 my $pidl;
113 my $basename = basename($idl_file, ".idl");
115 if (!defined($opt_output)) {
116 $output = $idl_file;
117 } else {
118 $output = $opt_output . $basename;
121 my($pidl_file) = util::ChangeExtension($output, ".pidl");
123 print "Compiling $idl_file\n";
125 if ($opt_parse) {
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";
132 } else {
133 $pidl = util::LoadStructure($pidl_file);
134 defined $pidl || die "Failed to load $pidl_file - maybe you need --parse\n";
137 if ($opt_dump) {
138 print IdlDump::Dump($pidl);
141 if ($opt_header) {
142 my($header) = util::ChangeExtension($output, ".h");
143 util::FileSave($header, IdlHeader::Parse($pidl));
146 if ($opt_client) {
147 my ($client) = util::ChangeExtension($output, "_c.c");
148 my $res = "";
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;
159 } else {
160 $res .= IdlClient::ParseInterface($x);
164 if ($need_dcom_register) {
165 $res .= IdlProxy::RegistrationFunction($pidl, $basename);
167 util::FileSave($client, $res);
170 if ($opt_server) {
171 my $h_filename = util::ChangeExtension($output, ".h");
172 my $plain = "";
173 my $dcom = "";
175 foreach my $x (@{$pidl}) {
176 next if ($x->{TYPE} ne "INTERFACE");
178 if (util::has_property($x, "object")) {
179 $dcom .= IdlStub::ParseInterface($x);
180 } else {
181 $plain .= IdlServer::ParseInterface($x);
185 if ($plain ne "") {
186 util::FileSave(util::ChangeExtension($output, "_s.c"), $plain);
189 if ($dcom ne "") {
190 $dcom = "
191 #include \"includes.h\"
192 #include \"$h_filename\"
193 #include \"rpc_server/dcerpc_server.h\"
194 #include \"rpc_server/common/common.h\"
196 $dcom
198 util::FileSave(util::ChangeExtension($output, "_d.c"), $dcom);
202 if ($opt_parser) {
203 my($parser) = util::ChangeExtension($output, ".c");
204 IdlParser::Parse($pidl, $parser);
207 if ($opt_eparser) {
209 # Generate regular .c and .h files for marshaling and
210 # unmarshaling.
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);
227 if ($opt_swig) {
228 my($filename) = $output;
229 $filename =~ s/\/ndr_/\//;
230 $filename = util::ChangeExtension($filename, ".i");
231 util::FileSave($filename, IdlSwig::Parse($pidl));
234 if ($opt_diff) {
235 my($tempfile) = util::ChangeExtension($output, ".tmp");
236 util::FileSave($tempfile, IdlDump::Dump($pidl));
237 system("diff -wu $idl_file $tempfile");
238 unlink($tempfile);
241 if ($opt_template) {
242 print IdlTemplate::Parse($pidl);
247 foreach my $filename (@ARGV) {
248 process_file($filename);