Blame maint/f77tof90

Packit 0848f5
#! /usr/bin/env perl
Packit 0848f5
# -*- Mode: perl; -*-
Packit 0848f5
#
Packit 0848f5
# f77tof90 indir outdir [ Makefile-template [Make-Append] ]
Packit 0848f5
# For each file in indir/*.[fF], create a corresponding file in outdir
Packit 0848f5
# with .f90/.F90, and with any include "mpif.h" replaced with use mpi
Packit 0848f5
# It also changes to the new comment style, because some compilers
Packit 0848f5
# use the comment style to choose other features of the language
Packit 0848f5
#
Packit 0848f5
# We also allow the file name to be modified to help out Windows, since
Packit 0848f5
# programs in a project need to have distinct names
Packit 0848f5
#
Packit 0848f5
use warnings;
Packit 0848f5
Packit 0848f5
$indir = $ARGV[0];
Packit 0848f5
$outdir = $ARGV[1];
Packit 0848f5
$makeTemplate = $ARGV[2];
Packit 0848f5
$makeAppend   = $ARGV[3];
Packit 0848f5
$convertToFreeForm    = 1;
Packit 0848f5
$convertToNewComments = 1;
Packit 0848f5
# Including a newline variable allows us to handle Unix and DOS source files
Packit 0848f5
$newline = "\n";
Packit 0848f5
Packit 0848f5
%replaceInclude = ( 'iodisp' => 'integer (kind=MPI_OFFSET_KIND) disp',
Packit 0848f5
		    'ioaint' => 'integer (kind=MPI_ADDRESS_KIND) aint',
Packit 0848f5
		    'iooffset' => 'integer (kind=MPI_OFFSET_KIND) offset',
Packit 0848f5
		    'type1aint' => 'integer (kind=MPI_ADDRESS_KIND) aint', 
Packit 0848f5
		    'typeaints' => 'integer (kind=MPI_ADDRESS_KIND) aint, aintv(max_asizev)', 
Packit 0848f5
		    'attr1aints' => 'integer (kind=MPI_ADDRESS_KIND) extrastate, valin, valout, val',
Packit 0848f5
		    'attraints' => 'integer (kind=MPI_ADDRESS_KIND) extrastate, valin, valout, val',
Packit 0848f5
		    'addsize' => 'integer (kind=MPI_ADDRESS_KIND) asize',
Packit 0848f5
                    'add1size' => 'integer (kind=MPI_ADDRESS_KIND) asize',
Packit 0848f5
	    );
Packit 0848f5
Packit 0848f5
%excludePrograms = ();
Packit 0848f5
$debugReplace = 0;
Packit 0848f5
$reportSkipped = 1;
Packit 0848f5
# --------------------------------------------------------------------------
Packit 0848f5
# Check the input arguments
Packit 0848f5
if ($indir eq "" || $outdir eq "") {
Packit 0848f5
    print STDERR "Usage: f77tof90 indir outdir [ makefile-template ]\n";
Packit 0848f5
    exit 1;
Packit 0848f5
}
Packit 0848f5
if ( ! -d $indir) {
Packit 0848f5
    print STDERR "Input directory $indir does not exist\n";
Packit 0848f5
    exit 1;
Packit 0848f5
}
Packit 0848f5
if (! -d $outdir) {
Packit 0848f5
    print STDERR "Output directory $outdir does not exist\n";
Packit 0848f5
    exit 1;
Packit 0848f5
}
Packit 0848f5
# --------------------------------------------------------------------------
Packit 0848f5
Packit 0848f5
Packit 0848f5
# --------------------------------------------------------------------------
Packit 0848f5
opendir( DIR, "$indir" );
Packit 0848f5
my @filelist = ();
Packit 0848f5
while ($file = readdir(DIR)) {
Packit 0848f5
    # Extract the extension
Packit 0848f5
    if ($file =~ /^(.*)\.([^\.]*)$/) {
Packit 0848f5
	$name = $1;
Packit 0848f5
	$ext  = $2;
Packit 0848f5
	# Special handling for C files, if any
Packit 0848f5
	if ($ext eq "c") {
Packit 0848f5
	    my $name90 = $name;
Packit 0848f5
            # don't transform "ctypesfromc" to "ctypesf90romc"
Packit 0848f5
            if ($name ne "ctypesfromc") {
Packit 0848f5
                $name90 =~ s/f/f90/g;
Packit 0848f5
            }
Packit 0848f5
	    &ConvertCFile( "$indir/$file", "$outdir/$name90.c.new" );
Packit 0848f5
	    &ReplaceIfDifferent( "$outdir/$name90.c", 
Packit 0848f5
				 "$outdir/$name90.c.new" );
Packit 0848f5
	    next;
Packit 0848f5
	}
Packit 0848f5
	# Skip if the file isn't a Fortran source file
Packit 0848f5
	if ($ext ne "f" && $ext ne "F") { next; }
Packit 0848f5
	&ConvertToF90( "$indir/$file", "$outdir/${name}90.${ext}90.new" );
Packit 0848f5
	&ReplaceIfDifferent( "$outdir/${name}90.${ext}90", 
Packit 0848f5
			     "$outdir/${name}90.${ext}90.new" );
Packit 0848f5
	$filelist[$#filelist+1] = $file;
Packit 0848f5
    }
Packit 0848f5
}
Packit 0848f5
closedir( DIR );
Packit 0848f5
Packit 0848f5
# &CreateMakefile( "filelist", $outdir );
Packit 0848f5
if (defined($makeTemplate) && $makeTemplate ne "" &&
Packit 0848f5
    -s "$indir/$makeTemplate") {
Packit 0848f5
    &ConvertMakefile( $indir, $outdir, $makeTemplate );
Packit 0848f5
    if (defined($makeAppend) && -s "$outdir/$makeAppend") {
Packit 0848f5
	# If there is a makeAppend in the output directory, then 
Packit 0848f5
	# append that to the generated makefile
Packit 0848f5
	&AppendFile( "$outdir/$makeAppend", "$outdir/$makeTemplate.new" );
Packit 0848f5
    }
Packit 0848f5
    &ReplaceIfDifferent( "$outdir/$makeTemplate", 
Packit 0848f5
			 "$outdir/$makeTemplate.new" );
Packit 0848f5
Packit 0848f5
    # unconditionally update the stamp file to assist the maintainer rebuild
Packit 0848f5
    # rules
Packit 0848f5
    open(STAMP, '>', "$outdir/Makefile.am-stamp");
Packit 0848f5
    print STAMP localtime()."\n";
Packit 0848f5
    close(STAMP);
Packit 0848f5
}
Packit 0848f5
if (-s "$indir/testlist" || -s "$indir/testlist.in") {
Packit 0848f5
    # We allow both testlist.in and testlist as source files;
Packit 0848f5
    # testlist.in gets priority
Packit 0848f5
    my $filename = "testlist";
Packit 0848f5
    if (-s "$indir/testlist.in") {
Packit 0848f5
	$filename = "testlist.in";
Packit 0848f5
    }
Packit 0848f5
    &ConvertTestlist( $indir, $outdir, $filename );
Packit 0848f5
    
Packit 0848f5
    if (-s "$outdir/testlist.ap") {
Packit 0848f5
	&AppendFile( "$outdir/testlist.ap", "$outdir/$filename.new" );
Packit 0848f5
    }
Packit 0848f5
    &ReplaceIfDifferent( "$outdir/$filename", "$outdir/$filename.new" );
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
exit 0;
Packit 0848f5
Packit 0848f5
# -----------------------------------------------------------------------------
Packit 0848f5
Packit 0848f5
sub ConvertToF90 {
Packit 0848f5
    my $infile = $_[0];
Packit 0848f5
    my $outfile = $_[1];
Packit 0848f5
    
Packit 0848f5
    open (INF, "<$infile" ) || die "Could not open $infile\n";
Packit 0848f5
    open (OUTF, ">$outfile" ) || die "Could not open $outfile\n";
Packit 0848f5
Packit 0848f5
    print OUTF "! This file created from $infile with f77tof90\n";
Packit 0848f5
    my $lastLine = "";
Packit 0848f5
    my $firstline = 1;
Packit 0848f5
    while (<INF>) {
Packit 0848f5
	if (/\r/) { $newline = "\r\n"; }
Packit 0848f5
	# Remove any end-of-line characters
Packit 0848f5
	s/[\r\n]*//g;
Packit 0848f5
        # The implicit none must not come before the use mpi statement,
Packit 0848f5
	# but in F77, it must come before the include mpif.h statement.
Packit 0848f5
	# Rather than try and fix this, rely on the F77 versions to 
Packit 0848f5
	# catch undeclared variables
Packit 0848f5
        if (/[Ii][Mm][Pp][Ll][Ii][Cc][Ii][Tt]\s+[Nn][Oo][Nn][Ee]/) { next; }
Packit 0848f5
	if (/^(\s*)include\s+[\'\"]mpif\.h/) {
Packit 0848f5
	    $_ = "$1use mpi";
Packit 0848f5
	}
Packit 0848f5
	# Allow the insertion of Fortran 90 only statements, such as
Packit 0848f5
	# interface definitions
Packit 0848f5
        if (/^CF90/) {
Packit 0848f5
	    s/^CF90/    /;
Packit 0848f5
	}
Packit 0848f5
    # Remove lines used only for F77, such as external MPI function declarations
Packit 0848f5
    if (/!\s*F77ONLY\s*$/i) {
Packit 0848f5
        $_ = "";
Packit 0848f5
    }
Packit 0848f5
	# Since we use interface statements for the error handlers,
Packit 0848f5
	# remove their external declaration
Packit 0848f5
	if (/^\s+external myerrhanfunc/) {
Packit 0848f5
	    s/^\s/!/;
Packit 0848f5
	}
Packit 0848f5
	if ($convertToNewComments) {
Packit 0848f5
	    s/^C/!/;
Packit 0848f5
	    s/^c/!/;
Packit 0848f5
	}	
Packit 0848f5
	# Update the special includes that are used to provide 
Packit 0848f5
	# address or offset sized types with ones the use the
Packit 0848f5
	# Fortran90 KIND style
Packit 0848f5
	if (/^(\s*)include\s+[\'\"]([\/\.\w]+)\.h[\"\']/) {
Packit 0848f5
	    my $leading     = $1;
Packit 0848f5
	    my $includename = $2;
Packit 0848f5
	    if (defined($replaceInclude{$includename})) {
Packit 0848f5
		$_ = $leading . $replaceInclude{$includename} . "\n";
Packit 0848f5
	    }
Packit 0848f5
	}
Packit 0848f5
Packit 0848f5
	# We need to handle the special case of the program
Packit 0848f5
	# name in spawn commands
Packit 0848f5
	if (/(.*)\"([\.\/\w]*spawn[^\"]*)\"(.*)/) {
Packit 0848f5
	    my $before = $1;
Packit 0848f5
	    my $name = $2;
Packit 0848f5
	    my $after = $3;
Packit 0848f5
	    $_ = $before . "\"" . $name . "90" . "\"" . $after;
Packit 0848f5
	}
Packit 0848f5
Packit 0848f5
	# We could also detect continuations in column six and 
Packit 0848f5
	# convert to free-form input by holding one line back.
Packit 0848f5
	if ($convertToFreeForm) {
Packit 0848f5
	    if (/^     \S(.*)/) {
Packit 0848f5
		$leftover = $1;
Packit 0848f5
		# This line contains a continuation marker
Packit 0848f5
		# Add a continuation marker to the previous line if
Packit 0848f5
		# it doesn't already have one
Packit 0848f5
		if (! ($lastline =~ /\&\s*$/) ) {
Packit 0848f5
	  	    $lastline .= " &";	   
Packit 0848f5
		}
Packit 0848f5
		$_ = "      \&$leftover";
Packit 0848f5
	    }
Packit 0848f5
	}
Packit 0848f5
	print OUTF "$lastline$newline" if (! $firstline);
Packit 0848f5
	$firstline = 0;
Packit 0848f5
	$lastline = $_;
Packit 0848f5
    }
Packit 0848f5
    print OUTF "$lastline$newline";
Packit 0848f5
Packit 0848f5
    close (INF);
Packit 0848f5
    close (OUTF);
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
#
Packit 0848f5
# A very simple routine for creating a version of a C file that refers
Packit 0848f5
# to F90 instead of F77.
Packit 0848f5
sub ConvertCFile {
Packit 0848f5
    my $infile = $_[0];
Packit 0848f5
    my $outfile = $_[1];
Packit 0848f5
    
Packit 0848f5
    open (INF, "<$infile" ) || die "Could not open $infile\n";
Packit 0848f5
    open (OUTF, ">$outfile" ) || die "Could not open $outfile\n";
Packit 0848f5
Packit 0848f5
    print OUTF "/* This file created from $infile with f77tof90 */\n";
Packit 0848f5
    while (<INF>) {
Packit 0848f5
	if (/\r/) { $newline = "\r\n"; }
Packit 0848f5
	# Remove any end-of-line characters
Packit 0848f5
	s/[\r\n]*//g;
Packit 0848f5
	# replace F77 with F90, mostly for CPP tests, except for name
Packit 0848f5
	# mapping
Packit 0848f5
	if (! /F77_NAME/) {
Packit 0848f5
	    s/F77/F90/g;
Packit 0848f5
	}
Packit 0848f5
	print OUTF "$_$newline";
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    close (INF);
Packit 0848f5
    close (OUTF);
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
# Create a makefile from a template.  Replace @EXECS@ with the programs
Packit 0848f5
# in the filelist.
Packit 0848f5
# CreateMakefile( "filelist", $outdir )
Packit 0848f5
sub CreateMakefile {
Packit 0848f5
    my $filelist = $_[0];
Packit 0848f5
    my $outdir   = $_[1];
Packit 0848f5
Packit 0848f5
    print STDERR "This function is not implemented\n";
Packit 0848f5
    return 0;
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
#
Packit 0848f5
# Take an existing makefile and perform the following transformations:
Packit 0848f5
# .f -> .f90, .F -> .F90
Packit 0848f5
# Others as necessary
Packit 0848f5
# ConvertMakefile( indir, outdir, filename )
Packit 0848f5
# By providing the filename, we can accept Makefile, Makefile.in, Makefile.ap,
Packit 0848f5
# Makefile.sm, or even nonstandard names such as buildscript.
Packit 0848f5
sub ConvertMakefile {
Packit 0848f5
    my ($indir, $outdir, $filename) = @_;
Packit 0848f5
    %excludePrograms = ();
Packit 0848f5
    my $saw_maintainercleanfiles = 0;
Packit 0848f5
    my $saw_extra_dist = 0;
Packit 0848f5
Packit 0848f5
    open( INF, "<$indir/$filename" ) || die "Cannot open $indir/$filename\n";
Packit 0848f5
    open( OUTF, ">$outdir/$filename.new" ) || die "Cannot open $outdir/$filename.new\n";
Packit 0848f5
    print OUTF "# This $filename generated automatically by f77tof90\n";
Packit 0848f5
    print OUTF "# from $indir/$filename.  DO NOT EDIT\n"; 
Packit 0848f5
    while (<INF>) {
Packit 0848f5
        if (not m/^\s*#/ and m/MAINTAINERCLEANFILES/) {
Packit 0848f5
            $saw_maintainercleanfiles = 1;
Packit 0848f5
        }
Packit 0848f5
        if (not m/^\s*#/ and m/EXTRA_DIST/) {
Packit 0848f5
            $saw_extra_dist = 1;
Packit 0848f5
        }
Packit 0848f5
Packit 0848f5
        # First, check for sources that are not present.  These
Packit 0848f5
	# may be derived files (see f77/io for an example).  For now,
Packit 0848f5
	# we'll skip these unless they are explicitly expected to not be present
Packit 0848f5
        # (by the presence of a "nodist_" prefix.
Packit 0848f5
	if (/^(nodist_)?(\w+)_SOURCES\s*=\s*(\w+\.f)/) {
Packit 0848f5
            my $nodist     = $1;
Packit 0848f5
	    my $sourcebase = $2;
Packit 0848f5
	    my $sourcename = $3;
Packit 0848f5
	    if (not $nodist and ! -s "$indir/$sourcename") {
Packit 0848f5
		print "Skipping source file $indir/$sourcename because it is not present\n" if $reportSkipped;
Packit 0848f5
		$excludePrograms{$sourcebase} = 1;
Packit 0848f5
		next; 
Packit 0848f5
	    }
Packit 0848f5
	}
Packit 0848f5
Packit 0848f5
        # Headers like f77/spawn/type1aints.h are not used in the f90 tests.
Packit 0848f5
        # They are instead replaced with appropriate "kind=" type declarations
Packit 0848f5
        # in a different part of this script.  So we drop any lines that add
Packit 0848f5
        # dependencies on a header.
Packit 0848f5
        if (m/^\w+f\.\$\(OBJEXT\):.*\.h/) {
Packit 0848f5
            my $chomped = $_;
Packit 0848f5
            chomp $_;
Packit 0848f5
            next;
Packit 0848f5
        }
Packit 0848f5
Packit 0848f5
        # convert program names from foof.f to foof90.f90
Packit 0848f5
        s/f_SOURCES/f90_SOURCES/g;
Packit 0848f5
        s/f_DEPENDENCIES/f90_DEPENDENCIES/g;
Packit 0848f5
	if (/f\.f/) {
Packit 0848f5
	    s/f\.f/f90.f90/g;
Packit 0848f5
	}
Packit 0848f5
	else {
Packit 0848f5
	    # Move files to f90
Packit 0848f5
	    s/\.f/.f90/g;
Packit 0848f5
	}
Packit 0848f5
	s/mtestf\.o/mtestf90.o/;
Packit 0848f5
	s/\.F/.F90/g;
Packit 0848f5
	s/f77/f90/g;
Packit 0848f5
	s/F77/FC/g;
Packit 0848f5
	# Update any per-program LDADD values
Packit 0848f5
        s/f_LDADD/f90_LDADD/g;
Packit 0848f5
	#
Packit 0848f5
	# Handle special cases:  
Packit 0848f5
	# Force the c2f2c test to use the f90 compiler
Packit 0848f5
	s/c2f2cf90_SOURCES.*/c2f2cf90_SOURCES = c2f2cf90.f90 c2f902c.c/;
Packit 0848f5
	s/c2f2ciof90_SOURCES.*/c2f2ciof90_SOURCES = c2f2ciof90.f90 c2f902cio.c/;
Packit 0848f5
#	s/c2f2ciof90_LDADD/c2f2cfio90_LDADD/g;
Packit 0848f5
	s/c2f2cwinf90_SOURCES.*/c2f2cwinf90_SOURCES = c2f2cwinf90.f90 c2f902cwin.c/;
Packit 0848f5
        s/c2fmult/c2f90mult/g;
Packit 0848f5
Packit 0848f5
	if (/EXTRA_PROGRAMS/) {
Packit 0848f5
	    s/allocmemf/allocmemf90/;   # allocmemf test is special 
Packit 0848f5
	}
Packit 0848f5
	# Handle the special case of C programs (used for f2c/c2f testing)
Packit 0848f5
	if (/^(\w+)_SOURCES(\s*=\s*)(\w+)\.c\s*$/) {
Packit 0848f5
	    my $progname = $1;
Packit 0848f5
	    my $spacing  = $2;
Packit 0848f5
	    my $name     = $3;
Packit 0848f5
            if ($name !~ m/ctypesfromc/) {
Packit 0848f5
                $name =~ s/f(?!90)/f90/;
Packit 0848f5
                $progname =~ s/f(?!90)/f90/;
Packit 0848f5
                $_ = "$progname" . "_SOURCES" . $spacing . $name . ".c\n";
Packit 0848f5
            }
Packit 0848f5
	}
Packit 0848f5
Packit 0848f5
        # Catch any bare "Xf" tests listed in noinst_PROGRAMS or
Packit 0848f5
        # EXTRA_PROGRAMS.  Check for "Xf.f" to avoid substituting any random
Packit 0848f5
        # word that ends in "f".  We also cheat a bit and look into the
Packit 0848f5
        # ioharness.defn in the indir directory for valid file names.
Packit 0848f5
        if (not m/^\s*#/) {
Packit 0848f5
            while (m/\b(\w+f)\b/g) {
Packit 0848f5
                my $word = $1;
Packit 0848f5
                next if $word eq "if" or $word eq "rf" or $word eq "endif"; # filter out some noise
Packit 0848f5
                if (-e "$indir/${word}.f" or
Packit 0848f5
                    0 == system(qq(grep 'TESTDEFN filename="${word}\\.f"' '$indir/ioharness.defn' >/dev/null 2>&1)))
Packit 0848f5
                {
Packit 0848f5
                    s/\b${word}\b/${word}90/g;
Packit 0848f5
                }
Packit 0848f5
                else
Packit 0848f5
                {
Packit 0848f5
                    print "Skipping word '${word}' because file $indir/${word}.f is not present\n" if $reportSkipped;
Packit 0848f5
                }
Packit 0848f5
            }
Packit 0848f5
        }
Packit 0848f5
Packit 0848f5
        # f90 makefiles should use the corresponding common automake fragment
Packit 0848f5
        s/Makefile_f77.mtest/Makefile_f90.mtest/g;
Packit 0848f5
Packit 0848f5
	# Eventually need some way to update directory paths (particularly
Packit 0848f5
	# relative ones) and add F90 compile rules when not present.
Packit 0848f5
	print OUTF $_;
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    my $mcf_plus = '';
Packit 0848f5
    if ($saw_maintainercleanfiles) {
Packit 0848f5
        $mcf_plus = '+';
Packit 0848f5
    }
Packit 0848f5
    my $ed_plus = '';
Packit 0848f5
    if ($saw_extra_dist) {
Packit 0848f5
        $ed_plus = '+';
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    my $testlist_ap = '';
Packit 0848f5
    if (-f "${outdir}/testlist.ap") {
Packit 0848f5
        $testlist_ap = 'testlist.ap';
Packit 0848f5
    }
Packit 0848f5
    my $makefile_ap = '';
Packit 0848f5
    if (-f "${outdir}/Makefile.ap") {
Packit 0848f5
        $makefile_ap = 'Makefile.ap';
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    # append a rule to help remake the f90 Makefile.am if the f77 Makefile.am is
Packit 0848f5
    # updated
Packit 0848f5
    print OUTF <
Packit 0848f5
Packit 0848f5
if MAINTAINER_MODE
Packit 0848f5
Packit 0848f5
# f77tof90 only replaces output files if the contents differ, so we must use a
Packit 0848f5
# separate timestamp file in order avoid constantly trying to remake the f90
Packit 0848f5
# copy of the Makefile when the f77 copy is updated in a way that does not
Packit 0848f5
# change its contents
Packit 0848f5
\$(srcdir)/Makefile.am: \$(srcdir)/Makefile.am-stamp
Packit 0848f5
Packit 0848f5
\$(srcdir)/Makefile.am-stamp: \$(master_top_srcdir)/${indir}/Makefile.am \$(master_top_srcdir)/maint/f77tof90
Packit 0848f5
\t( cd \$(master_top_srcdir) && ./maint/f77tof90 ${indir} ${outdir} Makefile.am Makefile.ap )
Packit 0848f5
Packit 0848f5
MAINTAINERCLEANFILES ${mcf_plus}= Makefile.am-stamp
Packit 0848f5
EXTRA_DIST ${ed_plus}= Makefile.am-stamp ${testlist_ap} ${makefile_ap}
Packit 0848f5
Packit 0848f5
endif MAINTAINER_MODE
Packit 0848f5
Packit 0848f5
EOT
Packit 0848f5
Packit 0848f5
    close( INF );
Packit 0848f5
    close( OUTF );
Packit 0848f5
    # The check on a file change is handled in the routine that calls this
Packit 0848f5
    # because we may append to this file first.
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
# Append infile to the end of inout file
Packit 0848f5
#( infile, inoutfile )
Packit 0848f5
sub AppendFile { 
Packit 0848f5
    my $infile = $_[0];
Packit 0848f5
    my $outfile = $_[1];
Packit 0848f5
    
Packit 0848f5
    open( INA, "<$infile" ) || die "Cannot open $infile\n";
Packit 0848f5
    open( OUTA, ">>$outfile" ) || die "Cannot open $outfile\n";
Packit 0848f5
    while (<INA>) {
Packit 0848f5
        print OUTA $_;
Packit 0848f5
    }
Packit 0848f5
    close(INA);
Packit 0848f5
    close(OUTA);
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
#
Packit 0848f5
# Replace old file with new file only if new file is different
Packit 0848f5
# Otherwise, remove new filename 
Packit 0848f5
sub ReplaceIfDifferent {
Packit 0848f5
    my ($oldfilename,$newfilename) = @_;
Packit 0848f5
    my $rc = 1;
Packit 0848f5
    if (-s $oldfilename) { 
Packit 0848f5
	$rc = system "cmp -s $newfilename $oldfilename";
Packit 0848f5
	$rc >>= 8;   # Shift right to get exit status
Packit 0848f5
    }
Packit 0848f5
    if ($rc != 0) {
Packit 0848f5
	print STDERR "Replacing $oldfilename\n";
Packit 0848f5
	if ($debugReplace && -s $oldfilename) {
Packit 0848f5
	    print STDERR "Differences are:";
Packit 0848f5
	    system "diff $newfilename $oldfilename";
Packit 0848f5
	}
Packit 0848f5
	# The files differ.  Replace the old file 
Packit 0848f5
	# with the new one
Packit 0848f5
	if (-s $oldfilename) {
Packit 0848f5
	    unlink $oldfilename;
Packit 0848f5
	}
Packit 0848f5
	rename $newfilename, $oldfilename || 
Packit 0848f5
	    die "Could not replace $oldfilename";
Packit 0848f5
    }
Packit 0848f5
    else {
Packit 0848f5
	unlink $newfilename;
Packit 0848f5
    }
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
# Change the names of the tests.  Remove any that were skipped from the 
Packit 0848f5
# Makefile.  Check for a  testlist.in before testlist
Packit 0848f5
sub ConvertTestlist {
Packit 0848f5
    my ($indir, $outdir, $filename) = @_;
Packit 0848f5
Packit 0848f5
    open( INF, "<$indir/$filename" ) || die "Cannot open $indir/$filename\n";
Packit 0848f5
    open( OUTF, ">$outdir/$filename.new" ) || die "Cannot open $outdir/$filename.new\n";
Packit 0848f5
    print OUTF "# This file generated by f77tof90\n";
Packit 0848f5
    while (<INF>) {
Packit 0848f5
	if (/^(\w+)\s/) {
Packit 0848f5
	    my $sourcebase = $1;
Packit 0848f5
	    if (defined($excludePrograms{$sourcebase})) { next; }
Packit 0848f5
	}
Packit 0848f5
	if (/^(\w+f)\s+(.*)/) {
Packit 0848f5
	    $_ = $1 . "90 "  . $2 . "\n";
Packit 0848f5
	}
Packit 0848f5
	elsif (/^c2fmult(\w*)\s+(.*)/) {
Packit 0848f5
	    # This is a special case for programs that are not Fortran
Packit 0848f5
	    # programs but are part of the Fortran tests; principly, these
Packit 0848f5
	    # are the tests of MPI handle conversion
Packit 0848f5
	    # note the \w* instead of \w+; this allows us to match both
Packit 0848f5
	    # c2fmult.c and c2fmultio.c
Packit 0848f5
	    $_ = "c2f90mult$1 $2\n";
Packit 0848f5
	}
Packit 0848f5
	elsif (/^\@ALLOCMEMF\@/) {
Packit 0848f5
	    # This is a special case for an optional feature (using
Packit 0848f5
	    # Cray-style pointers for MPI_Alloc_mem).
Packit 0848f5
	    $_ = "\@ALLOCMEMFC\@\n";
Packit 0848f5
	}
Packit 0848f5
	elsif (/^(\@\w+\@)(\s*\w+f)\s+(.*)/) {
Packit 0848f5
	    # This handles the case where an autoconf variable in the
Packit 0848f5
            # testlist.in file is used to optionally comment out a test
Packit 0848f5
	    $_ = $1 . $2 . "90 "  . $3 . "\n";
Packit 0848f5
	}
Packit 0848f5
	print OUTF $_;
Packit 0848f5
    }
Packit 0848f5
    close INF;
Packit 0848f5
    close OUTF;
Packit 0848f5
Packit 0848f5
}