r2704: Complain about 'object interfaces' that don't have version 0.0 (the standard
[samba.git] / source / build / pidl / pidl.pl
1 #!/usr/bin/perl -w
2
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
8
9 use strict;
10
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 parser;
21 use eparser;
22 use validator;
23 use util;
24 use template;
25 use swig;
26
27 my($opt_help) = 0;
28 my($opt_parse) = 0;
29 my($opt_dump) = 0;
30 my($opt_diff) = 0;
31 my($opt_header) = 0;
32 my($opt_template) = 0;
33 my($opt_server) = 0;
34 my($opt_parser) = 0;
35 my($opt_eparser) = 0;
36 my($opt_keep) = 0;
37 my($opt_swig) = 0;
38 my($opt_output);
39
40 my $idl_parser = new idl;
41
42 #####################################################################
43 # parse an IDL file returning a structure containing all the data
44 sub IdlParse($)
45 {
46     my $filename = shift;
47     my $idl = $idl_parser->parse_idl($filename);
48     util::CleanData($idl);
49     return $idl;
50 }
51
52
53 #########################################
54 # display help text
55 sub ShowHelp()
56 {
57     print "
58            perl IDL parser and code generator
59            Copyright (C) tridge\@samba.org
60
61            Usage: pidl.pl [options] <idlfile>
62
63            Options:
64              --help                this help page
65              --output OUTNAME      put output in OUTNAME.*
66              --parse               parse a idl file to a .pidl file
67              --dump                dump a pidl file back to idl
68              --header              create a C header file
69              --parser              create a C parser
70              --server              create server boilerplate
71              --template            print a template for a pipe
72              --eparser             create an ethereal parser
73              --diff                run diff on the idl and dumped output
74              --keep                keep the .pidl file
75            \n";
76     exit(0);
77 }
78
79 # main program
80 GetOptions (
81             'help|h|?' => \$opt_help, 
82             'output=s' => \$opt_output,
83             'parse' => \$opt_parse,
84             'dump' => \$opt_dump,
85             'header' => \$opt_header,
86             'server' => \$opt_server,
87             'template' => \$opt_template,
88             'parser' => \$opt_parser,
89             'eparser' => \$opt_eparser,
90             'diff' => \$opt_diff,
91             'keep' => \$opt_keep,
92             'swig' => \$opt_swig
93             );
94
95 if ($opt_help) {
96     ShowHelp();
97     exit(0);
98 }
99
100 sub process_file($)
101 {
102         my $idl_file = shift;
103         my $output;
104         my $pidl;
105
106         my $basename = basename($idl_file, ".idl");
107
108         if (!defined($opt_output)) {
109                 $output = $idl_file;
110         } else {
111                 $output = $opt_output . $basename;
112         }
113
114         my($pidl_file) = util::ChangeExtension($output, ".pidl");
115
116         print "Compiling $idl_file\n";
117
118         if ($opt_parse) {
119                 $pidl = IdlParse($idl_file);
120                 defined $pidl || die "Failed to parse $idl_file";
121                 IdlValidator::Validate($pidl);
122                 if ($opt_keep && !util::SaveStructure($pidl_file, $pidl)) {
123                             die "Failed to save $pidl_file\n";
124                 }
125         } else {
126                 $pidl = util::LoadStructure($pidl_file);
127                 defined $pidl || die "Failed to load $pidl_file - maybe you need --parse\n";
128         }
129
130         if ($opt_dump) {
131                 print IdlDump::Dump($pidl);
132         }
133
134         if ($opt_header) {
135                 my($header) = util::ChangeExtension($output, ".h");
136                 util::FileSave($header, IdlHeader::Parse($pidl));
137         }
138
139         if ($opt_server) {
140                 my($server) = util::ChangeExtension($output, "_s.c");
141                 util::FileSave($server, IdlServer::Parse($pidl));
142         }
143
144         if ($opt_parser) {
145                 my($parser) = util::ChangeExtension($output, ".c");
146                 IdlParser::Parse($pidl, $parser);
147         }
148
149         if ($opt_eparser) {
150                 my($parser) = dirname($output) . "/packet-dcerpc-$basename.c";
151                 IdlEParser::Parse($pidl, $parser);
152                 $parser = dirname($output) . "/packet-dcerpc-proto-$basename.h";
153                 IdlEParser::ParseHeader($pidl, $parser);
154                 my($header) = dirname($output) . "/packet-dcerpc-proto.h";
155                 open(OUT, ">>$header") || die "can't open $header";
156                 print OUT "#include \"ndr_$basename.h\"\n";
157                 print OUT "#include \"packet-dcerpc-proto-$basename.h\"\n";
158                 close(OUT);
159         }
160
161         if ($opt_swig) {
162                 my($filename) = $output;
163                 $filename =~ s/\/ndr_/\//;
164                 $filename = util::ChangeExtension($filename, ".i");
165                 util::FileSave($filename, IdlSwig::Parse($pidl));
166         }
167
168         if ($opt_diff) {
169                 my($tempfile) = util::ChangeExtension($output, ".tmp");
170                 util::FileSave($tempfile, IdlDump::Dump($pidl));
171                 system("diff -wu $idl_file $tempfile");
172                 unlink($tempfile);
173         }
174
175         if ($opt_template) {
176                 print IdlTemplate::Parse($pidl);
177         }
178 }
179
180
181 foreach my $filename (@ARGV) {
182         process_file($filename);
183 }