beginnings of the C parser generator
[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 use Getopt::Long;
11 use Data::Dumper;
12 use Parse::RecDescent;
13 use dump;
14 use header;
15 use parser;
16 use util;
17
18 my($opt_help) = 0;
19 my($opt_parse) = 0;
20 my($opt_dump) = 0;
21 my($opt_diff) = 0;
22 my($opt_header) = 0;
23 my($opt_parser) = 0;
24
25 #####################################################################
26 # parse an IDL file returning a structure containing all the data
27 sub IdlParse($)
28 {
29     # this autoaction allows us to handle simple nodes without an action
30 #    $::RD_TRACE = 1;
31     $::RD_AUTOACTION = q { 
32                           $#item==1 && ref($item[1]) eq "" ? 
33                           $item[1] : 
34                           "XX_" . $item[0] . "_XX[$#item]"  };
35     my($filename) = shift;
36     my($grammer) = util::FileLoad("idl.gram");    
37     my($parser) = Parse::RecDescent->new($grammer);
38     my($saved_sep) = $/;
39     undef $/;
40     my($idl) = $parser->idl(`cpp $filename`);
41     $/ = $saved_sep;
42     util::CleanData($idl);
43     return $idl;
44 }
45
46
47 #########################################
48 # display help text
49 sub ShowHelp()
50 {
51     print "
52            perl IDL parser and code generator
53            Copyright tridge\@samba.org
54
55            Usage: pidl.pl [options] <idlfile>
56
57            Options:
58              --help                this help page
59              --parse               parse a idl file to a .pidl file
60              --dump                dump a pidl file back to idl
61              --header              create a C header file
62              --parser              create a C parser
63              --diff                run diff on the idl and dumped output
64            \n";
65     exit(0);
66 }
67
68 # main program
69 GetOptions (
70             'help|h|?' => \$opt_help, 
71             'parse' => \$opt_parse,
72             'dump' => \$opt_dump,
73             'header' => \$opt_header,
74             'parser' => \$opt_parser,
75             'diff' => \$opt_diff
76             );
77
78 if ($opt_help) {
79     ShowHelp();
80     exit(0);
81 }
82
83 my($idl_file) = shift;
84 die "ERROR: You must specify an idl file to process" unless ($idl_file);
85
86 my($pidl_file) = util::ChangeExtension($idl_file, "pidl");
87
88 if ($opt_parse) {
89     print "Generating $pidl_file\n";
90     my($idl) = IdlParse($idl_file);
91     util::SaveStructure($pidl_file, $idl) || die "Failed to save $pidl_file";
92 }
93
94 if ($opt_dump) {
95     my($idl) = util::LoadStructure($pidl_file);
96     print IdlDump::Dump($idl);
97 }
98
99 if ($opt_header) {
100     my($idl) = util::LoadStructure($pidl_file);
101     my($header) = util::ChangeExtension($idl_file, "h");
102     print "Generating $header\n";
103     util::FileSave($header, IdlHeader::Dump($idl));
104 }
105
106 if ($opt_parser) {
107     my($idl) = util::LoadStructure($pidl_file);
108     my($parser) = util::ChangeExtension($idl_file, "c");
109     print "Generating $parser\n";
110     util::FileSave($parser, IdlParser::Dump($idl));
111 }
112
113 if ($opt_diff) {
114     my($idl) = util::LoadStructure($pidl_file);
115     my($tempfile) = util::ChangeExtension($idl_file, "tmp");
116     util::FileSave($tempfile, IdlDump::Dump($idl));
117     system("diff -wu $idl_file $tempfile");
118     unlink($tempfile);
119 }