#!/usr/bin/env perl

# Make list of files containing source code.  The source list contains all
# .F90, .f90, .F, .f, .c and .cpp files in a specified list of directories. 
# The directories are specified one per line in a file called Filepath which
# this script tries to open in the current directory.  The current
# directory is prepended to the specified list of directories.  If Filepath
# doesn't exist then only the source files in the current directory are
# listed.
# The list of source files is written to the file Srcfiles.

# Check usage:
@ARGV == 0                 or usage();

if ( open(FILEPATH,"< Filepath") ) {
    @paths = <FILEPATH>;
    close( FILEPATH );
} else {
    @paths = ();
}
chomp @paths;
unshift(@paths, '.');
foreach $dir (@paths) {  # (could check that directories exist here)
    $dir =~ s!/?\s*$!!;  # remove / and any whitespace at end of directory name
    ($dir) = glob $dir;  # Expand tildes in path names.
}

# Loop through the directories and add each filename as a hash key.  This
# automatically eliminates redunancies.
%src = ();
foreach $dir (@paths) {
    @filenames = (glob("$dir/*.[Ffc]"), glob("$dir/*.[Ff]90"), glob("$dir/*.cpp"));
    foreach $filename (@filenames) {
	$filename =~ s!.*/!!;                   # remove part before last slash
	$src{$filename} = 1;
    }
    @templates = glob("$dir/*.F90.in");
    foreach $filename (@templates) {
	$filename =~ s!.*/!!;                   # remove part before last slash
	my $dfile = $filename;
	$dfile =~ s/\.in//;
	delete $src{$dfile} if(defined $src{$dfile});
	$src{$filename} = 1;
    }
}

my @srcfiles;
my $foundcnt=0;
my $writenew=1;
if(-e "Srcfiles"){    # file already exists, do not update if no changes are required
    open(SRC,"Srcfiles");
    @srcfiles = <SRC>;
    close(SRC);
    $writenew=0;
    foreach $file (@srcfiles){
	chomp $file;
	if($src{$file}){
	    $src{$file}=0;
	}else{
	    $writenew=1;  # A srcfile was removed
	    last;
	}

    }
    foreach $file (keys %src){
	if($src{$file} == 1){
	    $writenew=1;  # A srcfile was added
	    last;
	}
    }
}

if($writenew==1){
    open(SRC,"> Srcfiles")     or die "Can't open Srcfiles\n";

    foreach $file ( sort keys %src ) {
	print SRC "$file\n";
    }

    close( SRC );
}
#--------------------------------------------------------------------------------------

sub usage {
    ($ProgName = $0) =~ s!.*/!!;            # name of program
    die <<EOF
SYNOPSIS
     $ProgName
DESCRIPTION
     The $ProgName utility assumes the existence of an input file
     ./Filepath, and writes an output file ./Srcfiles that contains
     the names of all the files that match the patterns *.F90, *.F,
     and *.c in all the directories from ./Filepath plus ./.  The
     files are listed one per line.
EOF
}
