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