#! /usr/bin/env perl

use warnings;
use strict;
use File::Temp;
use File::Copy;

my $include="-I/usr/include -I/usr/include/smpi";

foreach my $fortran (@ARGV) {
   my $output = $fortran;
   $output =~ s/.f$/.c/;

   #print "F2C INPUT : ".$fortran."\n";
   #print "F2C OUTPUT: ".$output."\n";

   my$outputdir = $output;
   $outputdir=~s/[^\/]*\.c$//g;
   #print "F2C DIR   : ".$outputdir."\n";

   my $tmp = new File::Temp;
   $tmp->autoflush(1);
   #print "f2c -d$outputdir $include -w -a $fortran\n";
   `f2c -d$outputdir $include -w -a $fortran`;
   die "F2C failed\n" if $?;
   open F2C,"<$output" or die "Unable to open file $output";
   my $started = 0;
   print $tmp "#ifndef INTEGER_STAR_8\n";
   print $tmp "#define INTEGER_STAR_8\n";
   print $tmp "#endif\n";
   print $tmp "#include <stdlib.h>\n";
   print $tmp "#include <smpif.h>\n";
   while(<F2C>) {
      chomp;
      if(/\/\* Common Block Declarations \*\//) {
         $started = 1;
      }
      if($started) {
         if(/^} (.*?);/) {
            $_ = "}* __attribute__((weak)) $1 = NULL;\n";
         } elsif(/^#define\s*(\S*)\s*\(?([^.]*)(\..*?)?\)?$/) {
            $_ = "#define $1 $2\[smpi_current_rank\]";
            if(defined $3) {
               $_ .= $3;
            }
            $_ .= "\n";
            $_ .= "\nvoid __attribute__((weak,constructor)) __preinit_$1(void) {\n  if(!$2) $2 = malloc(smpi_global_size() * sizeof(*$2));\n}\n";
            $_ .= "\nvoid __attribute__((weak,destructor)) __postfini_$1(void) {\n  free($2);\n  $2 = NULL;\n}\n";
         }
      }
      if(/\/\* Table of constant values \*\// || /MAIN__/) {
         $started = 0;
      }
      $_ =~ s/(mpi_[\w]*_)_/$1/g;
      if(/\/* Main program alias \*\/\s*int\s+.*\s*\(\s*\)\s*{(.*)}/) {
         $_ = "int smpi_simulated_main_(int argc, char** argv) { smpi_process_init(&argc, &argv); $1 }\n";
      }
      print $tmp "$_\n";
   }
   close F2C;
   copy($tmp->filename,$output) or die "Copy failed: $!\n";
}
