lib-addns: ensure that allocated buffer are pre set to 0
[sfrench/samba-autobuild/.git] / script / mkparamdefs.pl
1 #!/usr/bin/perl
2 # Generate loadparm tables for loadparm.c
3 # by Andrew Bartlett
4 # based on mkproto.pl Written by Jelmer Vernooij
5 # based on the original mkproto.sh by Andrew Tridgell
6
7 use strict;
8
9 # don't use warnings module as it is not portable enough
10 # use warnings;
11
12 use Getopt::Long;
13 use File::Basename;
14 use File::Path;
15
16 #####################################################################
17 # read a file into a string
18
19 my $file = undef;
20 my $public_define = undef;
21 my $_public = "";
22 my $_private = "";
23 my $public_data = \$_public;
24 my $builddir = ".";
25 my $srcdir = ".";
26 my $generate_scope = undef;
27
28 sub public($)
29 {
30         my ($d) = @_;
31         $$public_data .= $d;
32 }
33
34 sub usage()
35 {
36         print "Usage: mkparamdefs.pl [options] [c files]\n";
37         print "OPTIONS:\n";
38         print "  --srcdir=path          Read files relative to this directory\n";
39         print "  --builddir=path        Write file relative to this directory\n";
40         print "  --generate-scope=[GLOBAL|LOCAL]        Filter which definitions to generate\n";
41         print "  --help                 Print this help message\n\n";
42         exit 0;
43 }
44
45 GetOptions(
46         'file=s' => sub { my ($f,$v) = @_; $file = $v; },
47         'srcdir=s' => sub { my ($f,$v) = @_; $srcdir = $v; },
48         'builddir=s' => sub { my ($f,$v) = @_; $builddir = $v; },
49         'generate-scope=s' => sub { my ($f,$v) = @_; $generate_scope = $v; },
50         'help' => \&usage
51 ) or exit(1);
52
53 sub normalize_define($$)
54 {
55         my ($define, $file) = @_;
56
57         if (not defined($define) and defined($file)) {
58                 $define = "__" . uc($file) . "__";
59                 $define =~ tr{./}{__};
60                 $define =~ tr{\-}{_};
61         } elsif (not defined($define)) {
62                 $define = '_S3_PARAM_H_';
63         }
64
65         return $define;
66 }
67
68 $public_define = normalize_define($public_define, $file);
69
70 sub file_load($)
71 {
72     my($filename) = @_;
73     local(*INPUTFILE);
74     open(INPUTFILE, $filename) or return undef;
75     my($saved_delim) = $/;
76     undef $/;
77     my($data) = <INPUTFILE>;
78     close(INPUTFILE);
79     $/ = $saved_delim;
80     return $data;
81 }
82
83 sub print_header($$$)
84 {
85         my ($file, $header_name,$generate_scope) = @_;
86         $file->("#ifndef $header_name\n");
87         $file->("#define $header_name\n\n");
88 $file->("/* This file was automatically generated by mkparamdefs.pl. DO NOT EDIT */\n\n");
89         $file->("/**\n");
90         if ($generate_scope eq "GLOBAL") {
91             $file->(" * This structure describes global (ie., server-wide) parameters.\n");
92             $file->(" */\n");
93             $file->("struct loadparm_global \n");
94             $file->("{\n");
95             $file->("\tTALLOC_CTX *ctx; /* Context for talloced members */\n");
96         } elsif ($generate_scope eq "LOCAL") {
97             $file->(" * This structure describes a single service.\n");
98             $file->(" */\n");
99             $file->("struct loadparm_service \n");
100             $file->("{\n");
101         }
102 }
103
104 sub print_footer($$$)
105 {
106         my ($file, $header_name, $generate_scope) = @_;
107         $file->("LOADPARM_EXTRA_" . $generate_scope . "S\n");
108         $file->("};\n");
109         $file->("\n#endif /* $header_name */\n\n");
110 }
111
112 sub handle_loadparm($$$)
113 {
114         my ($file,$line,$generate_scope) = @_;
115
116         my $scope;
117         my $type;
118         my $name;
119         my $var;
120
121         if ($line =~ /^FN_(GLOBAL|LOCAL)_(CONST_STRING|STRING|BOOL|bool|CHAR|INTEGER|LIST)\((\w+),(.*)\)/o) {
122                 $scope = $1;
123                 $type = $2;
124                 $name = $3;
125                 $var = $4;
126         } elsif ($line =~ /^FN_(GLOBAL|LOCAL)_PARM_(CONST_STRING|STRING|BOOL|bool|CHAR|INTEGER|LIST)\((\w+),(.*)\)/o) {
127                 $scope = $1;
128                 $type = $2;
129                 $name = $3;
130                 $var = $4;
131         } else {
132                 return;
133         }
134         my %tmap = (
135             "BOOL" => "bool ",
136             "CONST_STRING" => "char *",
137             "STRING" => "char *",
138             "INTEGER" => "int ",
139             "CHAR" => "char ",
140             "LIST" => "const char **",
141             );
142
143         if ($scope eq $generate_scope) {
144             $file->("\t$tmap{$type} $var;\n");
145         }
146 }
147
148 sub process_file($$)
149 {
150         my ($file, $filename) = @_;
151
152         $filename =~ s/\.o$/\.c/g;
153
154         if ($filename =~ /^\//) {
155                 open(FH, "<$filename") or die("Failed to open $filename");
156         } elsif (!open(FH, "< $builddir/$filename")) {
157             open(FH, "< $srcdir/$filename") || die "Failed to open $filename";
158         }
159
160         my $comment = undef;
161         my $incomment = 0;
162         while (my $line = <FH>) {
163                 if ($line =~ /^\/\*\*/) {
164                         $comment = "";
165                         $incomment = 1;
166                 }
167
168                 if ($incomment) {
169                         $comment .= $line;
170                         if ($line =~ /\*\//) {
171                                 $incomment = 0;
172                         }
173                 }
174
175                 # these are ordered for maximum speed
176                 next if ($line =~ /^\s/);
177
178                 next unless ($line =~ /\(/);
179
180                 next if ($line =~ /^\/|[;]/);
181
182                 if ($line =~ /^static (FN_.*)/) {
183                         handle_loadparm($file, $1, $generate_scope);
184                 } elsif ($line =~ /^FN_/) {
185                         handle_loadparm($file, $line, $generate_scope);
186                 }
187                 next;
188         }
189
190         close(FH);
191 }
192
193
194 print_header(\&public, $public_define, $generate_scope);
195
196 process_file(\&public, $_) foreach (@ARGV);
197 print_footer(\&public, $public_define, $generate_scope);
198
199 if (not defined($file)) {
200         print STDOUT $$public_data;
201 }
202
203 mkpath(dirname($file), 0, 0755);
204 open(PUBLIC, ">$file") or die("Can't open `$file': $!");
205 print PUBLIC "$$public_data";
206 close(PUBLIC);