a bit neater way of emitting code
[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
7 # released under the GNU GPL
8
9 use strict;
10
11 use FindBin qw($RealBin);
12 use lib "$RealBin";
13 use Getopt::Long;
14 use idl;
15 use dump;
16 use header;
17 use parser;
18 use eparser;
19 use client;
20 use util;
21
22 my($opt_help) = 0;
23 my($opt_parse) = 0;
24 my($opt_dump) = 0;
25 my($opt_diff) = 0;
26 my($opt_header) = 0;
27 my($opt_parser) = 0;
28 my($opt_eparser) = 0;
29 my($opt_client);
30 my($opt_keep) = 0;
31 my($opt_output);
32
33 #####################################################################
34 # parse an IDL file returning a structure containing all the data
35 sub IdlParse($)
36 {
37     # this autoaction allows us to handle simple nodes without an action
38 #    $::RD_TRACE = 1;
39     $::RD_AUTOACTION = q { 
40                           $#item==1 && ref($item[1]) eq "" ? 
41                           $item[1] : 
42                           "XX_" . $item[0] . "_XX[$#item]"  };
43     my($filename) = shift;
44     my($parser) = idl->new;
45     my($saved_sep) = $/;
46
47     undef $/;
48     my($idl) = $parser->idl(`cpp $filename | grep -v '^#'`);
49     $/ = $saved_sep;
50     util::CleanData($idl);
51     return $idl;
52 }
53
54
55 #########################################
56 # display help text
57 sub ShowHelp()
58 {
59     print "
60            perl IDL parser and code generator
61            Copyright (C) tridge\@samba.org
62
63            Usage: pidl.pl [options] <idlfile>
64
65            Options:
66              --help                this help page
67              --output OUTNAME      put output in OUTNAME.*
68              --parse               parse a idl file to a .pidl file
69              --dump                dump a pidl file back to idl
70              --header              create a C header file
71              --parser              create a C parser
72              --eparser             create an ethereal parser
73              --client FILENAME     create client calls in FILENAME
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             'parser' => \$opt_parser,
88             'eparser' => \$opt_eparser,
89             'client=s' => \$opt_client,
90             'diff' => \$opt_diff,
91             'keep' => \$opt_keep
92             );
93
94 if ($opt_help) {
95     ShowHelp();
96     exit(0);
97 }
98
99 my($idl_file) = shift;
100 die "ERROR: You must specify an idl file to process" unless ($idl_file);
101
102 if (!defined($opt_output)) {
103         $opt_output = $idl_file;
104 }
105
106 my($pidl_file) = util::ChangeExtension($opt_output, "pidl");
107
108 if ($opt_parse) {
109     print "Generating $pidl_file from $idl_file\n";
110     my($idl) = IdlParse($idl_file);
111     defined $idl || die "Failed to parse $idl_file";
112     util::SaveStructure($pidl_file, $idl) || die "Failed to save $pidl_file";
113 }
114
115 if ($opt_dump) {
116     my($idl) = util::LoadStructure($pidl_file);
117     print IdlDump::Dump($idl);
118 }
119
120 if ($opt_header) {
121     my($idl) = util::LoadStructure($pidl_file);
122     my($header) = util::ChangeExtension($opt_output, "h");
123     print "Generating $header\n";
124     util::FileSave($header, IdlHeader::Parse($idl));
125 }
126
127 if ($opt_parser) {
128     my($idl) = util::LoadStructure($pidl_file);
129     my($parser) = util::ChangeExtension($opt_output, "c");
130     print "Generating $parser\n";
131     IdlParser::Parse($idl, $parser);
132 }
133
134 if ($opt_eparser) {
135     my($idl) = util::LoadStructure($pidl_file);
136     my($parser) = util::ChangeExtension($opt_output, "c");
137     print "Generating $parser for ethereal\n";
138     util::FileSave($parser, IdlEParser::Parse($idl));
139 }
140
141 if ($opt_client) {
142     my($idl) = util::LoadStructure($pidl_file);
143     my($client) = util::ChangeExtension($opt_client, "c");
144     print "Generating $client client calls\n";
145     util::FileSave($client, IdlClient::Parse($idl));
146 }
147
148 if ($opt_diff) {
149     my($idl) = util::LoadStructure($pidl_file);
150     my($tempfile) = util::ChangeExtension($opt_output, "tmp");
151     util::FileSave($tempfile, IdlDump::Dump($idl));
152     system("diff -wu $idl_file $tempfile");
153     unlink($tempfile);
154 }
155
156 if (!$opt_keep) {
157         system("rm -f $pidl_file");
158 }