2011-06-20 09:48:12 +04:00
#!/usr/bin/perl
# Generate loadparm tables for loadparm.c
# by Andrew Bartlett
# based on mkproto.pl Written by Jelmer Vernooij
# based on the original mkproto.sh by Andrew Tridgell
use strict ;
# don't use warnings module as it is not portable enough
# use warnings;
use Getopt::Long ;
use File::Basename ;
use File::Path ;
#####################################################################
# read a file into a string
my $ file = undef ;
my $ public_define = undef ;
my $ _public = "" ;
my $ _private = "" ;
my $ public_data = \ $ _public ;
my $ builddir = "." ;
my $ srcdir = "." ;
my $ generate_scope = undef ;
sub public ($)
{
my ( $ d ) = @ _ ;
$$ public_data . = $ d ;
}
sub usage ()
{
print "Usage: mkparamdefs.pl [options] [c files]\n" ;
print "OPTIONS:\n" ;
print " --srcdir=path Read files relative to this directory\n" ;
print " --builddir=path Write file relative to this directory\n" ;
print " --generate-scope=[GLOBAL|LOCAL] Filter which definitions to generate\n" ;
print " --help Print this help message\n\n" ;
exit 0 ;
}
GetOptions (
'file=s' = > sub { my ( $ f , $ v ) = @ _ ; $ file = $ v ; } ,
'srcdir=s' = > sub { my ( $ f , $ v ) = @ _ ; $ srcdir = $ v ; } ,
'builddir=s' = > sub { my ( $ f , $ v ) = @ _ ; $ builddir = $ v ; } ,
'generate-scope=s' = > sub { my ( $ f , $ v ) = @ _ ; $ generate_scope = $ v ; } ,
'help' = > \ & usage
) or exit ( 1 ) ;
sub normalize_define ($$)
{
my ( $ define , $ file ) = @ _ ;
if ( not defined ( $ define ) and defined ( $ file ) ) {
$ define = "__" . uc ( $ file ) . "__" ;
$ define =~ tr { . / } { __ } ;
$ define =~ tr { \ - } { _ } ;
} elsif ( not defined ( $ define ) ) {
$ define = '_S3_PARAM_H_' ;
}
return $ define ;
}
$ public_define = normalize_define ( $ public_define , $ file ) ;
sub file_load ($)
{
my ( $ filename ) = @ _ ;
local ( * INPUTFILE ) ;
open ( INPUTFILE , $ filename ) or return undef ;
my ( $ saved_delim ) = $/ ;
undef $/ ;
my ( $ data ) = <INPUTFILE> ;
close ( INPUTFILE ) ;
$/ = $ saved_delim ;
return $ data ;
}
sub print_header ($$$)
{
my ( $ file , $ header_name , $ generate_scope ) = @ _ ;
$ file - > ( "#ifndef $header_name\n" ) ;
$ file - > ( "#define $header_name\n\n" ) ;
2011-08-24 10:31:12 +04:00
$ file - > ( "/* This file was automatically generated by mkparamdefs.pl. DO NOT EDIT */\n\n" ) ;
2011-06-20 09:48:12 +04:00
$ file - > ( "/**\n" ) ;
if ( $ generate_scope eq "GLOBAL" ) {
$ file - > ( " * This structure describes global (ie., server-wide) parameters.\n" ) ;
$ file - > ( " */\n" ) ;
$ file - > ( "struct loadparm_global \n" ) ;
2012-07-23 06:49:46 +04:00
$ file - > ( "{\n" ) ;
$ file - > ( "\tTALLOC_CTX *ctx; /* Context for talloced members */\n" ) ;
2011-06-20 09:48:12 +04:00
} elsif ( $ generate_scope eq "LOCAL" ) {
$ file - > ( " * This structure describes a single service.\n" ) ;
$ file - > ( " */\n" ) ;
$ file - > ( "struct loadparm_service \n" ) ;
2012-07-23 06:49:46 +04:00
$ file - > ( "{\n" ) ;
2011-06-20 09:48:12 +04:00
}
}
2011-07-01 08:36:25 +04:00
sub print_footer ($$$)
2011-06-20 09:48:12 +04:00
{
my ( $ file , $ header_name , $ generate_scope ) = @ _ ;
$ file - > ( "LOADPARM_EXTRA_" . $ generate_scope . "S\n" ) ;
$ file - > ( "};\n" ) ;
$ file - > ( "\n#endif /* $header_name */\n\n" ) ;
}
2011-07-01 08:36:25 +04:00
sub handle_loadparm ($$$)
2011-06-20 09:48:12 +04:00
{
my ( $ file , $ line , $ generate_scope ) = @ _ ;
2011-07-01 08:36:25 +04:00
my $ scope ;
my $ type ;
my $ name ;
my $ var ;
2011-06-20 09:48:12 +04:00
if ( $ line =~ /^FN_(GLOBAL|LOCAL)_(CONST_STRING|STRING|BOOL|bool|CHAR|INTEGER|LIST)\((\w+),(.*)\)/o ) {
2011-07-01 08:36:25 +04:00
$ scope = $ 1 ;
$ type = $ 2 ;
$ name = $ 3 ;
$ var = $ 4 ;
} elsif ( $ line =~ /^FN_(GLOBAL|LOCAL)_PARM_(CONST_STRING|STRING|BOOL|bool|CHAR|INTEGER|LIST)\((\w+),(.*)\)/o ) {
$ scope = $ 1 ;
$ type = $ 2 ;
$ name = $ 3 ;
$ var = $ 4 ;
} else {
return ;
}
my % tmap = (
2011-10-06 09:35:39 +04:00
"BOOL" = > "bool " ,
2011-07-01 08:36:25 +04:00
"CONST_STRING" = > "char *" ,
"STRING" = > "char *" ,
"INTEGER" = > "int " ,
"CHAR" = > "char " ,
"LIST" = > "const char **" ,
) ;
if ( $ scope eq $ generate_scope ) {
$ file - > ( "\t$tmap{$type} $var;\n" ) ;
2011-06-20 09:48:12 +04:00
}
}
2011-07-01 08:36:25 +04:00
sub process_file ($$)
2011-06-20 09:48:12 +04:00
{
my ( $ file , $ filename ) = @ _ ;
$ filename =~ s/\.o$/\.c/g ;
if ( $ filename =~ /^\// ) {
open ( FH , "<$filename" ) or die ( "Failed to open $filename" ) ;
} elsif ( ! open ( FH , "< $builddir/$filename" ) ) {
open ( FH , "< $srcdir/$filename" ) || die "Failed to open $filename" ;
}
my $ comment = undef ;
my $ incomment = 0 ;
2011-07-01 08:36:25 +04:00
while ( my $ line = <FH> ) {
if ( $ line =~ /^\/\*\*/ ) {
2011-06-20 09:48:12 +04:00
$ comment = "" ;
$ incomment = 1 ;
}
if ( $ incomment ) {
$ comment . = $ line ;
if ( $ line =~ /\*\// ) {
$ incomment = 0 ;
}
2011-07-01 08:36:25 +04:00
}
2011-06-20 09:48:12 +04:00
# these are ordered for maximum speed
next if ( $ line =~ /^\s/ ) ;
2011-07-01 08:36:25 +04:00
2011-06-20 09:48:12 +04:00
next unless ( $ line =~ /\(/ ) ;
next if ( $ line =~ /^\/|[;]/ ) ;
2011-07-01 08:36:25 +04:00
if ( $ line =~ /^static (FN_.*)/ ) {
handle_loadparm ( $ file , $ 1 , $ generate_scope ) ;
} elsif ( $ line =~ /^FN_/ ) {
2011-06-20 09:48:12 +04:00
handle_loadparm ( $ file , $ line , $ generate_scope ) ;
}
next ;
}
close ( FH ) ;
}
print_header ( \ & public , $ public_define , $ generate_scope ) ;
process_file ( \ & public , $ _ ) foreach ( @ ARGV ) ;
print_footer ( \ & public , $ public_define , $ generate_scope ) ;
if ( not defined ( $ file ) ) {
print STDOUT $$ public_data ;
}
mkpath ( dirname ( $ file ) , 0 , 0755 ) ;
2011-07-01 08:36:25 +04:00
open ( PUBLIC , ">$file" ) or die ( "Can't open `$file': $!" ) ;
2011-06-20 09:48:12 +04:00
print PUBLIC "$$public_data" ;
close ( PUBLIC ) ;