fcd189d8cd5be6b1eb24f4751173615cba2c22f1
[samba.git] / source4 / 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              --swig                create swig wrapper file
74              --diff                run diff on the idl and dumped output
75              --keep                keep the .pidl file
76            \n";
77     exit(0);
78 }
79
80 # main program
81 GetOptions (
82             'help|h|?' => \$opt_help, 
83             'output=s' => \$opt_output,
84             'parse' => \$opt_parse,
85             'dump' => \$opt_dump,
86             'header' => \$opt_header,
87             'server' => \$opt_server,
88             'template' => \$opt_template,
89             'parser' => \$opt_parser,
90             'eparser' => \$opt_eparser,
91             'diff' => \$opt_diff,
92             'keep' => \$opt_keep,
93             'swig' => \$opt_swig
94             );
95
96 if ($opt_help) {
97     ShowHelp();
98     exit(0);
99 }
100
101 sub process_file($)
102 {
103         my $idl_file = shift;
104         my $output;
105         my $pidl;
106
107         my $basename = basename($idl_file, ".idl");
108
109         if (!defined($opt_output)) {
110                 $output = $idl_file;
111         } else {
112                 $output = $opt_output . $basename;
113         }
114
115         my($pidl_file) = util::ChangeExtension($output, ".pidl");
116
117         print "Compiling $idl_file\n";
118
119         if ($opt_parse) {
120                 $pidl = IdlParse($idl_file);
121                 defined @$pidl || die "Failed to parse $idl_file";
122                 IdlValidator::Validate($pidl);
123                 if ($opt_keep && !util::SaveStructure($pidl_file, $pidl)) {
124                             die "Failed to save $pidl_file\n";
125                 }
126         } else {
127                 $pidl = util::LoadStructure($pidl_file);
128                 defined $pidl || die "Failed to load $pidl_file - maybe you need --parse\n";
129         }
130
131         if ($opt_dump) {
132                 print IdlDump::Dump($pidl);
133         }
134
135         if ($opt_header) {
136                 my($header) = util::ChangeExtension($output, ".h");
137                 util::FileSave($header, IdlHeader::Parse($pidl));
138         }
139
140         if ($opt_server) {
141                 my($server) = util::ChangeExtension($output, "_s.c");
142                 util::FileSave($server, IdlServer::Parse($pidl));
143         }
144
145         if ($opt_parser) {
146                 my($parser) = util::ChangeExtension($output, ".c");
147                 IdlParser::Parse($pidl, $parser);
148         }
149
150         if ($opt_eparser) {
151                 my($parser) = dirname($output) . "/packet-dcerpc-$basename.c";
152                 IdlEParser::Parse($pidl, $parser);
153                 $parser = dirname($output) . "/packet-dcerpc-proto-$basename.h";
154                 IdlEParser::ParseHeader($pidl, $parser);
155                 my($header) = dirname($output) . "/packet-dcerpc-proto.h";
156                 open(OUT, ">>$header") || die "can't open $header";
157                 print OUT "#include \"ndr_$basename.h\"\n";
158                 print OUT "#include \"packet-dcerpc-proto-$basename.h\"\n";
159                 close(OUT);
160         }
161
162         if ($opt_swig) {
163                 my($filename) = $output;
164                 $filename =~ s/\/ndr_/\//;
165                 $filename = util::ChangeExtension($filename, ".i");
166                 util::FileSave($filename, IdlSwig::Parse($pidl));
167         }
168
169         if ($opt_diff) {
170                 my($tempfile) = util::ChangeExtension($output, ".tmp");
171                 util::FileSave($tempfile, IdlDump::Dump($pidl));
172                 system("diff -wu $idl_file $tempfile");
173                 unlink($tempfile);
174         }
175
176         if ($opt_template) {
177                 print IdlTemplate::Parse($pidl);
178         }
179 }
180
181
182 foreach my $filename (@ARGV) {
183         process_file($filename);
184 }