# This is a perl script, invoked from a shell

use warnings;  # this doesn't work on older versions of perl


sub GenConfigHeader {

   my $line;
   local *CFILE;
   local *CFILEOUT;

   open(CFILE, "< cfile");
   open(CFILEOUT, "> cfileout");

   while ($line = <CFILE>) {

      $line =~ s/@\{(.*?)\}/$Config{$1}/ge;

      print CFILEOUT $line;

   }

   close(CFILE);
   close(CFILEOUT);

   system("cp cfileout ../include/NTL/config.h");

}




sub RemoveProg {

# This should work on unix and cygwin on windows

   my ($name) = @_;

   unlink($name);  unlink("$name.exe");

}


sub RunProg {

   my ($name) = @_;
   my $val;
   my $res;

   system("make wntl.a");
   RemoveProg($name);
   system("make $name");

   print "\n*** running $name...";

   $val = `./$name`;

   if ($? != 0) {
      $res = "999999999999999";
   }
   else {
      ($res) = ( $val =~ /^([0-9]*)/ );
   }

   print $val, "\n";

   return $res;

}


############################################################



system("make InitSettings");

@lines = `./InitSettings`;

%Config = (

'NTL_LONG_LONG'        => 0,
'NTL_AVOID_FLOAT'      => 0,
'NTL_SPMM_UL'          => 0,
'NTL_SPMM_ULL'         => 0,
'NTL_SPMM_ASM'         => 0,
'NTL_TBL_REM'          => 0,
'NTL_AVOID_BRANCHING'  => 0,
'NTL_GF2X_ALTCODE'     => 0,
'NTL_GF2X_ALTCODE1'    => 0,
'NTL_GF2X_NOINLINE'    => 0,
'NTL_FFT_BIGTAB'       => 0,
'NTL_FFT_LAZYMUL'      => 0,

'WIZARD_HACK'          => '#define NTL_WIZARD_HACK',

);

foreach $line (@lines) {
   chomp($line);
   ($name, $val) = ($line =~ /(.*?)=(.*)/);
   $Config{$name} = $val;
}





#  set AVOID_BRANCHING, SPMM, and FFT flags...try all combinations 


$time = "999999999999999";
$aflag = "default";
$bflag = "default";
$cflag = "default";
$dflag = "default";


foreach $aflag1 ("default", "NTL_AVOID_BRANCHING") {
   foreach $bflag1 ("default", "NTL_SPMM_UL", "NTL_SPMM_ULL", "NTL_SPMM_ASM") {
      foreach $cflag1 ("default", "NTL_FFT_BIGTAB") {
         foreach $dflag1 ("default", "NTL_FFT_LAZYMUL") {


            $Config{$aflag1} = 1;
            $Config{$bflag1} = 1;
            $Config{$cflag1} = 1;
            $Config{$dflag1} = 1;


            if ($Config{"NTL_FFT_LAZYMUL"}) {

               if ($Config{"NTL_FFT_BIGTAB"} == 0 ||
                   ($Config{"NTL_SPMM_ULL"} == 0 && $Config{"NTL_SPMM_ASM"} == 0)) {

                  $Config{$aflag1} = 0;
                  $Config{$bflag1} = 0;
                  $Config{$cflag1} = 0;
                  $Config{$dflag1} = 0;

                  print "skip: $aflag1 $bflag1 $cflag1 $dflag1\n";
                  next;
               }
              
            }

            print "run: $aflag1 $bflag1 $cflag1 $dflag1\n";
            GenConfigHeader();
            $time1 = RunProg("Poly1TimeTest");

            if ($time1 < $time) {
               $aflag = $aflag1;
               $bflag = $bflag1;
               $cflag = $cflag1;
               $dflag = $dflag1;
               $time = $time1;
            }

            $Config{$aflag1} = 0;
            $Config{$bflag1} = 0;
            $Config{$cflag1} = 0;
            $Config{$dflag1} = 0;
            unlink("FFT.o");  
            unlink("ZZ_pX.o");  
         }
      }
   }
}

$Config{$aflag} = 1;
$Config{$bflag} = 1;
$Config{$cflag} = 1;
$Config{$dflag} = 1;
unlink("lip.o");   #  AVOID_BRANCHING affects this too
unlink("ZZ_pX.o");   # FFT_BIGTABS and FFT_LAZYMUL affect this
unlink("lzz_pX.o");   # FFT_BIGTABS and FFT_LAZYMUL affect this


# set the flags GF2X_NOINLINE and GF2X_ALTCODE...try all pairs

$time = "999999999999999";
$aflag = "default";
$bflag = "default";

foreach $aflag1 ("default", "NTL_GF2X_NOINLINE") {
   foreach $bflag1 ("default", "NTL_GF2X_ALTCODE", "NTL_GF2X_ALTCODE1") {

      $Config{$aflag1} = 1;
      $Config{$bflag1} = 1;
      GenConfigHeader();
      $time1 = RunProg("GF2XTimeTest");

      if ($time1 < $time) {
	 $aflag = $aflag1;
	 $bflag = $bflag1;
	 $time = $time1;
      }

      $Config{$aflag1} = 0;
      $Config{$bflag1} = 0;
      unlink("GF2X.o");
   }
}

$Config{$aflag} = 1;
$Config{$bflag} = 1;



if ($Config{"NTL_GMP_LIP"} == 0) {

   # GMP is not the primary long integer package
   # Choose between default, AVOID_FLOAT, and LONG_LONG implementatsions

   $time = "999999999999999";
   $flag = "default";

   foreach $flag1 ("default", "NTL_AVOID_FLOAT", "NTL_LONG_LONG") {
      $Config{$flag1} = 1;
      GenConfigHeader(); 
      $time1 = RunProg("MulTimeTest");

      if ($time1 < $time) {
	 $flag = $flag1;
	 $time = $time1;
      }

      $Config{$flag1} = 0;
      unlink("lip.o");
   }

   $Config{$flag} = 1;


   # finally, now set TBL_REM

   GenConfigHeader();
   $time = RunProg("PolyTimeTest");

   $Config{"NTL_TBL_REM"} = 1;
   GenConfigHeader();
   unlink("lip.o");

   $time1 = RunProg("PolyTimeTest");

   if ($time1 >= $time) {
      $Config{"NTL_TBL_REM"} = 0;
   } 

}

$Config{'WIZARD_HACK'} = "";
GenConfigHeader();

print "\n\n*** the wizard is done!!\n\n"; 

system("make DispSettings");
system("./DispSettings");


