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