: # use perl                                  -*- mode: Perl; -*-
	eval 'exec perl -S $0 "$@"'
		if $running_under_some_shell;

#
# compile.pl - AFT element file compiler.
#
# Copyright (C) 1996-2002 Todd Coram.  All rights reserved.

my $VERSION="2.05a";

# Hash of elements
my %element = ();

# Hash of variables
my %postvar = ();

my $preamble;
my $postamble;

my $postfilter;
my $prefilter;

$date = scalar localtime;

(@ARGV == 0) && do {
    print (STDERR "Usage: aft-compile element_file.dat \n");
    exit 2;
};

$infile = $ARGV[0];
$outfile = $ARGV[0];
$outfile =~ s/([^.])\.dat$/$1\.pm/;

open(OUT, ">$outfile") || die "Can't open $outfile for output!";

select(OUT);

print (STDERR "Compiling $infile into $outfile ...\n");
print "# AFT Output Elements.\n";
print "# !!DO NOT EDIT!! This file was automatically generated by aft-compile ";
print "v$VERSION on $date\n";
print "# See http://www.maplefish.com/todd/aft.html for details.\n";

&processFile($infile);

sub processFile {
    my ($fname) = @_;
    local *IN;
    open(IN, $fname) || die "Can't open data file: $fname";

    my $inPreamble = 0;


    while (<IN>) {
	chop;
	# Skip comment lines
	next if (/^(\s*\#|\Z)/ && !$inPreamble &&  !$inPostamble);
#	 /^(\s*\#|\Z)/ && ($inPreamble || $inPostamble) && next;	

	/^use (.+)/ && do {
	    print STDERR "Using features from $1...\n";
	    print "\n# Using features from $1.\n";
	    &processFile($1);
	};

	# Enter and exit preambles and postambles states.
	#
	/^\s*Preamble\s*\{/ && ($inPreamble = 1, $preamble = '', next);
	/^\s*\}\s*Preamble/ && ($inPreamble = 0, next);
	/^\s*Postamble\s*\{/ && ($inPostamble = 1, $postamble = '', next);
	/^\s*\}\s*Postamble/ && ($inPostamble = 0, next);
    
	# Read in the preamble and postamble text.
	#
	$inPreamble && ($preamble .= $_."\n", next);
	$inPostamble && ($postamble .= $_."\n", next);

        # Parse: preFilter into pairs (stored one after other in the array).
	#
	/^\s*(preFilter)\s*([^\s]+)\s*([^\s]*)/ && do {
	    push(@prefilter, "\$line=~s/$2/$3/g;");
	    next;
	};

	# Parse: postFilter into pairs (stored one after other in the array).
	#
	/^\s*(postFilter)\s*([^\s]+)\s+([^\s]+)/ && do {
	    push(@postfilter, "\$line=~s/$2/$3/g;");
	    next;
	};

	# Post filtering variables
	#
	/^SET\s+(\w+)\s*=\s*/ && ($postvar{$1} = $', next);

	# Elements
	#
	/^\s*([^\s]+)\s*/ && ($element{$1} = $');
    }
    close(IN);
}


print "package AFT_OUTPUT;\n\n";
print 'use vars qw ($filePreamble $filePostamble %elem %pragma_postvar);'."\n\n";
print '$filePreamble = \'\';	# Holds preamble for output file.'."\n";
print '$filePostamble = \'\';	# Holds postamble for output file.'."\n";
print '%elem = ();		# Element commands for producing output file.';
print '%pragma_postvar = ();	# Variables for substitution post-filtering.'."\n";
print "\n\nsub initElements {\n";

$interpolate = ($element{"interpolate"} =~ 'no') ? 0 : 1;
print "\t\%pragma_postvar = (\n";
foreach $item (keys %postvar) {
    print "\t\t'$item' =>\t '$postvar{$item}',\n";
}
print "\t);\n";

print "\t\%elem = (\n";
foreach $item  (keys %element) {
  if ($element{$item} =~ /^\<Undefined/) {
    print (STDERR "Undefined element: [$item]\n");
  }
  if ($interpolate) {
    # Quote nasty things they may get in the way
    $element{$item} =~ s/([\'\@\$\%])/\\$1/g; 
    print "\t\t'$item' =>\t qq'$element{$item}',\n";
  } else {
    $element{$item} =~ s/([\'])/\\$1/g; 
    print "\t\t'$item' =>\t '$element{$item}',\n";
    }
}
print "\t);\n";


print "\n## Preamble:\n\n";
$preamble =~ s/([\'])/\\$1/g; 
print "\$filePreamble = '$preamble';\n";
print "\n## Postamble:\n\n";
$postamble =~ s/([\'])/\\$1/g; 
print "\$filePostamble = '$postamble';\n";

print "}\n\n";

print "\n## Prefilter subroutine:\n\n";

print "sub prefilter {\n";
print "   my (\$line) = \@_;\n";
print "   ".join("\n   ", @prefilter);
print "\n   return \$line;\n}\n";

print "\n## Postfilter subroutine:\n\n";

print "sub postfilter {\n";
print "   my (\$line) = \@_;\n";
print "   ".join("\n   ", @postfilter);
print "\n   return \$line;\n}\n";

print "\n1;\n";

