#!/usr/local/bin/perl

require 5.003;

if (scalar(@ARGV) <= 0) {
    printf STDERR "No storage methods are available\n";
    exit(1);
}

foreach $file (@ARGV) {
    open(CFG, $file) || die "$!";
    while (<CFG>) {
	chomp;

	s/^\s+//;
	s/\s+$//;
	if (/^name\s*=\s*(\S+)/) {
	    $method = $1;
	    if (defined($methods{$method})) {
		print STDERR "$method has already been defined\n";
		exit(1);
	    } else {
		$methods{$method} = $file;
	    }
	}
	if (/^number\s*=\s*(\d+)/) {
	    $number = $1;
	    if (defined($number{$number})) {
		print STDERR "Method number $number was already allocated in $number{$number}\n";
		exit(1);
	    }
	    $number{$number} = $file;
	    $methodnum{$file} = $number;
	    next;
	}
    }
    close(CFG);
}

open(DEF, ">methods.c.new");
print DEF "/* This file is automatically generated by buildconfig */\n\n";
print DEF "#include \"methods.h\"\n";

foreach $method (keys %methods) {
    $path = $methods{$method};
    $path =~ s/\.\///;
    $path =~ s/method\.config//g;
    print DEF "#include \"$path$method", ".h\"\n";
}
print DEF "\n";

print DEF "STORAGE_METHOD storage_methods[", scalar(keys(%methods)), "] = {\n";

foreach $method (keys %methods) {
    print "Storage method '$method' configured\n";
    if ($first) {
	print DEF " },\n";
    }
    print DEF "\t{ \"$method\", TOKEN_", uc($method), ", \n\t  ";
    print DEF $method, "_init, ", $method, "_store, \n\t  ", $method, "_retrieve, ";
    print DEF $method, "_next, \n\t  ", $method, "_freearticle, ", $method, "_cancel, \n\t  ";
    print DEF $method, "_shutdown";
    $first++;
}

print DEF " }\n};\n\n";
close(DEF);
`cmp -s methods.c methods.c.new`;
if ($? == 0) { unlink("methods.c.new"); }
else { unlink("methods.c"); rename("methods.c.new","methods.c"); }

open(H, ">methods.h.new");
print H "/* This file is automatically generated by buildconfig */\n\n";
print H "#ifndef __METHODS_H__\n";
print H "#define __METHODS_H__\n\n";
print H "#include <interface.h>\n\n";
print H "#define NUM_STORAGE_METHODS\t", scalar(keys(%methods)), "\n\n";
foreach $method (keys %methods) {
    printf H "#define TOKEN_%-40s%d\n", uc($method), $methodnum{$methods{$method}};
}
print H "\n";
print H "extern STORAGE_METHOD storage_methods[NUM_STORAGE_METHODS];\n\n";
print H "#endif /* __METHODS_H__ */\n";
close(H);

open(LIST, ">Make.methods");
print LIST "# This file is automatically generated by buildconfig\n\n";
print LIST "SUBDIR = ";
foreach $method (keys %methods) {
    $path = $methods{$method};
    $path =~ s/\.\///;
    $path =~ s/\/method\.config//;
    print LIST "$path ";
}
print LIST "\n";
close(LIST);
`cmp -s methods.h methods.h.new`;
if ($? == 0) { unlink("methods.h.new"); }
else { unlink("methods.h"); rename("methods.h.new","methods.h"); }
