s3-waf: Reorder rpc_server wscript_build file.
[nivanova/samba-autobuild/.git] / script / mks3param.pl
1 #!/usr/bin/perl
2 # Generate loadparm interfaces tables for Samba3/Samba4 integration
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
27 sub public($)
28 {
29         my ($d) = @_;
30         $$public_data .= $d;
31 }
32
33 sub usage()
34 {
35         print "Usage: mks3param.pl [options] [c files]\n";
36         print "OPTIONS:\n";
37         print "  --srcdir=path          Read files relative to this directory\n";
38         print "  --builddir=path        Write file relative to this directory\n";
39         print "  --help                 Print this help message\n\n";
40         exit 0;
41 }
42
43 GetOptions(
44         'file=s' => sub { my ($f,$v) = @_; $file = $v; },
45         'srcdir=s' => sub { my ($f,$v) = @_; $srcdir = $v; },
46         'builddir=s' => sub { my ($f,$v) = @_; $builddir = $v; },
47         'help' => \&usage
48 ) or exit(1);
49
50 sub normalize_define($$)
51 {
52         my ($define, $file) = @_;
53
54         if (not defined($define) and defined($file)) {
55                 $define = "__" . uc($file) . "__";
56                 $define =~ tr{./}{__};
57                 $define =~ tr{\-}{_};
58         } elsif (not defined($define)) {
59                 $define = '_S3_PARAM_H_';
60         }
61
62         return $define;
63 }
64
65 $public_define = normalize_define($public_define, $file);
66
67 sub file_load($)
68 {
69     my($filename) = @_;
70     local(*INPUTFILE);
71     open(INPUTFILE, $filename) or return undef;
72     my($saved_delim) = $/;
73     undef $/;
74     my($data) = <INPUTFILE>;
75     close(INPUTFILE);
76     $/ = $saved_delim;
77     return $data;
78 }
79
80 sub print_header($$)
81 {
82         my ($file, $header_name) = @_;
83         $file->("#ifndef $header_name\n");
84         $file->("#define $header_name\n\n");
85         $file->("/* This file was automatically generated by mks3param.pl. DO NOT EDIT */\n\n");
86         $file->("struct loadparm_s3_helpers\n");
87         $file->("{\n");
88         $file->("\tconst char * (*get_parametric)(struct loadparm_service *, const char *type, const char *option);\n");
89         $file->("\tstruct parm_struct * (*get_parm_struct)(const char *param_name);\n");
90         $file->("\tvoid * (*get_parm_ptr)(struct loadparm_service *service, struct parm_struct *parm);\n");
91         $file->("\tstruct loadparm_service * (*get_service)(const char *service_name);\n");
92         $file->("\tstruct loadparm_service * (*get_default_loadparm_service)(void);\n");
93         $file->("\tstruct loadparm_service * (*get_servicebynum)(int snum);\n");
94         $file->("\tint (*get_numservices)(void);\n");
95         $file->("\tbool (*load)(const char *filename);\n");
96         $file->("\tbool (*set_cmdline)(const char *pszParmName, const char *pszParmValue);\n");
97         $file->("\tvoid (*dump)(FILE *f, bool show_defaults, int maxtoprint);\n");
98 }
99
100 sub print_footer($$) 
101 {
102         my ($file, $header_name) = @_;
103         $file->("};");
104         $file->("\n#endif /* $header_name */\n\n");
105 }
106
107 sub handle_loadparm($$) 
108 {
109         my ($file,$line) = @_;
110
111         # Local parameters don't need the ->s3_fns because the struct
112         # loadparm_service is shared and lpcfg_service() checks the ->s3_fns
113         # hook
114         #
115         # STRING isn't handled as we do not yet have a way to pass in a memory context nor
116         # do we have a good way of dealing with the % macros yet.
117
118         if ($line =~ /^FN_(GLOBAL)_(CONST_STRING|BOOL|bool|CHAR|INTEGER|LIST)\((\w+),.*\)/o) {
119                 my $scope = $1;
120                 my $type = $2;
121                 my $name = $3;
122
123                 my %tmap = (
124                             "BOOL" => "bool ",
125                             "CONST_STRING" => "const char *",
126                             "STRING" => "const char *",
127                             "INTEGER" => "int ",
128                             "CHAR" => "char ",
129                             "LIST" => "const char **",
130                             );
131
132                 $file->("\t$tmap{$type} (*$name)(void);\n");
133         }
134 }
135
136 sub process_file($$) 
137 {
138         my ($file, $filename) = @_;
139
140         $filename =~ s/\.o$/\.c/g;
141
142         if ($filename =~ /^\//) {
143                 open(FH, "<$filename") or die("Failed to open $filename");
144         } elsif (!open(FH, "< $builddir/$filename")) {
145             open(FH, "< $srcdir/$filename") || die "Failed to open $filename";
146         }
147
148         my $comment = undef;
149         my $incomment = 0;
150         while (my $line = <FH>) {             
151                 if ($line =~ /^\/\*\*/) { 
152                         $comment = "";
153                         $incomment = 1;
154                 }
155
156                 if ($incomment) {
157                         $comment .= $line;
158                         if ($line =~ /\*\//) {
159                                 $incomment = 0;
160                         }
161                 } 
162
163                 # these are ordered for maximum speed
164                 next if ($line =~ /^\s/);
165               
166                 next unless ($line =~ /\(/);
167
168                 next if ($line =~ /^\/|[;]/);
169
170                 if ($line =~ /^FN_/) {
171                         handle_loadparm($file, $line);
172                 }
173                 next;
174         }
175
176         close(FH);
177 }
178
179
180 print_header(\&public, $public_define);
181
182 process_file(\&public, $_) foreach (@ARGV);
183 print_footer(\&public, $public_define);
184
185 if (not defined($file)) {
186         print STDOUT $$public_data;
187 }
188
189 mkpath(dirname($file), 0, 0755);
190 open(PUBLIC, ">$file") or die("Can't open `$file': $!"); 
191 print PUBLIC "$$public_data";
192 close(PUBLIC);
193