#! /usr/bin/env perl

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

my $include="-I/build/buildd-simgrid_3.7.1-1-s390-UnkfNN/simgrid-3.7.1/include -I/build/buildd-simgrid_3.7.1-1-s390-UnkfNN/simgrid-3.7.1/include/smpi -I/usr/include -I/usr/include/smpi";

foreach my $fortran (@ARGV) {
   my $output = $fortran;
   $output =~ s/.f$/.c/;
   my $tmp = new File::Temp;
   $tmp->autoflush(1);
   `f2c $include -w -a $fortran`;
   die "F2C failed\n" if $?;
   open F2C,"<$output";
   my $started = 0;
   my $cutext = 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;
      }
      if(/extern \/\* Subroutine \*\//) {
         $cutext = 1;
      }
      if($cutext) {
         if(/;$/) {
            $cutext = 0;
         }
         next;
      }
      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";
}
