#!/usr/bin/perl -w
# configen.pl -- automatic config file parser generator written for frox.
# Needs a template file (in C), and a variable definitions file.
# This is the only perl program I have ever written, and it probably shows. 

if (scalar @ARGV !=3) {
	print STDERR "Usage $0 defs template output\n";
	exit 1;
}

open DEFS, $ARGV[0]
  or die "Can't open definitions file: $!";

open TEMPLATE, $ARGV[1]
  or die "Can't open template file: $!";

open OUTPUT, ">$ARGV[2]"
  or die "Can't open output file: $!";

while(<DEFS>){
	next unless /\S/;
	next if /^#/;
	chomp;
	push @defs, $_;
}

%i = ( "name" => 0,
       "type" => 1,
       "var" => 2,
       "cl" => 3,
       "reload" => 4,
       "needed" => 5,
       "default" => 6 );

while(<TEMPLATE>){
	if(/%_REPLACE_/){
		if(/%_REPLACE_OPTIONS_INIT_%/) {opt_init();}
		if(/%_REPLACE_OPTIONS_DEFAULTS_%/) {opt_defaults();}
		if(/%_REPLACE_OPTIONS_DEFINITION_%/) {opt_define();}
		if(/%_REPLACE_COMMENT_%/) {print_comment();}
	} else {
		print OUTPUT;
	}
}	
exit 0;
	
sub opt_init {
	foreach(@defs){
		if(/^(ifdef|endif)/){
			print OUTPUT "#$_\n";
			next;
		}
		@tmp=split;
		if(scalar @tmp != 7) {
			print STDERR "Wrong number of args in template file\n";
			print STDERR "\"$_\"\n";
			exit 1;
		}

		if($tmp[$i{name}] =~ /^-$/) {$tmp[$i{name}]=""};
		print OUTPUT '  {"'.$tmp[$i{name}].'",';
		print OUTPUT " " x (16-length $tmp[$i{name}]);

		print OUTPUT "$tmp[$i{type}],";
		print OUTPUT " " x (8 - length $tmp[$i{type}]);

		print OUTPUT "&config.$tmp[$i{var}],";
		print OUTPUT " " x (12 - length $tmp[$i{var}]);

		if($tmp[$i{cl}] =~ /^-$/) { print OUTPUT "'\\0', ";}
		else { print OUTPUT "'$tmp[$i{cl}]',  ";}

		print OUTPUT "$tmp[$i{reload}],";
		print OUTPUT " " x (6 - length $tmp[$i{needed}]);

		print OUTPUT "$tmp[$i{needed}]";
		print OUTPUT " " x (5 - length $tmp[$i{needed}]);

		print OUTPUT "},\n"
	}
        print OUTPUT "  {0, 0, 0, 0, 0, 0}\n";
}

sub opt_defaults {
	foreach(@defs){
		if(/^(ifdef|endif)/){
			print OUTPUT "#$_\n";
			next;
		}
		@tmp=split;
		if(scalar @tmp != 7) 
		  {die "Wrong number of args in template file" ;}

		next if $tmp[$i{default}] =~ /^-$/;
		if($tmp[$i{type}] =~ /PRTRNGE/) {
		  print OUTPUT "\tsstr_cpy2(tmp, \"$tmp[$i{name}] $tmp[$i{default}]\");\n";
		  print OUTPUT "\tparse_line(tmp);\n";
		} else {
		  print OUTPUT "\tconfig.$tmp[$i{var}] = $tmp[$i{default}];\n";
		}
	}
}

sub opt_define {
	foreach(@defs){
		next if /^(ifdef|endif)/; # Always define, just in case. #

		@tmp=split;
		if(scalar @tmp != 7) 
		  {die "Wrong number of args in template file" ;}

		elsif($tmp[$i{type}] =~ /^BOOL$/) {
			print OUTPUT "\tint $tmp[$i{var}];\n";
		}
		elsif($tmp[$i{type}] =~ /^(FILENAME|DIRECTRY|STRING)$/) {
			print OUTPUT "\tchar * $tmp[$i{var}];\n";
		}
		elsif($tmp[$i{type}] =~ /^ADDRESS$/) {
			print OUTPUT "\tstruct in_addr $tmp[$i{var}];\n";
		}
		elsif($tmp[$i{type}] =~ /^ADDRPRT$/) {
			print OUTPUT "\tstruct sockaddr_in $tmp[$i{var}];\n";
		}
		elsif($tmp[$i{type}] =~ /^INT$/) {
			print OUTPUT "\tint $tmp[$i{var}];\n";
		}
		elsif($tmp[$i{type}] =~ /^PRTRNGE$/) {
			print OUTPUT "\tint $tmp[$i{var}]"."[2];\n";
		}
		elsif($tmp[$i{type}] =~ /^ACL$/) {
			print OUTPUT "\tstruct acl_list $tmp[$i{var}];\n";
		}
		elsif($tmp[$i{type}] =~ /^SUBSECT$/) {
			print OUTPUT "\tstruct subsect_list $tmp[$i{var}];\n";
		}
	}
}

sub print_comment {
	print OUTPUT "*****   This file was autogenerated by $0 from\n";
	print OUTPUT "*****   $ARGV[0] and $ARGV[1]\n";
	print OUTPUT "*****   CHANGES TO THIS FILE WILL BE LOST. Please\n";
	print OUTPUT "*****   edit $ARGV[0] or $ARGV[1] instead\n";
}
