#!/usr/local/sbin/perl -w
use strict;

sub usage () {
    die << "EOM";
Usage: $0 <output_file_name> <fortran_source_file> <dir> <dir> ...
Read the given source file.  Put equivalent source in output_file_name,
with all include statements replaced by whatever they included.  You
should have at least one directory on the include path, otherwise
there's no point.

If the output file already exists, and its contents would be the same
as the contents we would put into it, then we do not modify it.  This
sometimes saves a compilation.

We're doing this because g77 generates wrong line numbers when you
have nested include files, which makes debugging difficult.
EOM
}

use FileHandle;

sub readFile ($$);

sub readFile ($$) {
    my ($filename, $includepath) = @_;
    my $fh = new FileHandle $filename, "r";
    if (!defined ($fh)) {
	die "Can't read $filename: $!";
    }
    print "C fixinclude is starting to read from $filename\n";
    my $lineNumber = 0;
    for (;;) {
	my $line = <$fh>;
	last unless defined $line;
	$lineNumber++;
	if ($line =~ m!^\s*include\s*'(.*)'\s*$!i) {
	    my $foundfile = "";
	    my $dir;
	    foreach $dir (@$includepath) {
		if (-r "$dir/$1") {
		    $foundfile = "$dir/$1";
		}
	    }
	    if ($foundfile) {
		readFile ($foundfile, $includepath);
	    } else {
		die "Can't find $1 in the path @$includepath";
	    }
	    print "C fixinclude is resuming reading from $filename line $lineNumber\n";
	} else {
	    print $line;
	}
    }
}

sub main () {
    usage () unless @ARGV > 2;
    my $outputfile = shift (@ARGV);
    my $filename = shift (@ARGV);
    if (! -r $filename) {
	die "Can't read $filename: $!";
    }
    my @path = @ARGV;
    my $dir;
    foreach $dir (@path) {
	if (! -d $dir) {
	    die "$dir is not a directory";
	}
    }
    my $tmpoutput = "$outputfile.tmp$$";
    open (STDOUT, ">$tmpoutput") || die "Can't write $tmpoutput: $!";
    readFile ($filename, \@path);
    close (STDOUT) || die "Can't close $tmpoutput: $!";
    if (system ("cmp --quiet $tmpoutput $outputfile")) {
	rename ($tmpoutput, $outputfile)
	    || die "Can't rename $tmpoutput to $outputfile: $!";
    } else {
	unlink ($tmpoutput) || die "Could not delete $tmpoutput: $!";
    }
}

main ();
