#!/usr/bin/perl -w
#
# $Id: configpp,v 1.2 2003/07/31 22:38:25 mdb Exp $
#
# Preprocesses a configuration file (a .dop file, for instance), executing
# any include directives located in the file.

use File::Basename;

my %files = ();
my $file = shift or die "Usage: $0 file [key=value key=value...]\n";

my %subs;
while ($pair = shift) {
    if ($pair =~ m/(\S+)=(\S+)/) {
        $subs{$1} = $2;
    } else {
        warn "Unable to parse substitution '$pair'.\n";
    }
}
my $scount = keys %subs;

# change into the directory occupied by the file
chdir(dirname($file));
$file = basename($file);

# process this file
read_file($file, "");

sub read_file {
    my ($path, $parent) = @_;

    # do circular reference checking
    if (defined $files{$path}) {
        die "Detected circular inclusion [file=$parent, incl=$path].\n";
    }
    $files{$path} = 1;

    # read the file
    my $FILE;
    open($FILE, "$path") or die "Can't read include file '$path': $!\n";
    while (<$FILE>) {
        if (m/^.include \"([^\"]*)\"/) {
            # process the inclusion
            read_file($1, $path);

        } elsif ($scount > 0 && m/\@[\S]+\@/) {
            # handle any substitutions
            while (m/\@([-A-Za-z_.]+)\@/) {
                my $key = $1;
                my $value = $subs{$key};
                $value = $key unless (defined $value);
                $_ =~ s/\@$key\@/$value/;
            }
            print $_;

        } else {
            print $_;
        }
    }
    close($FILE);
    undef $files{$path};
}
