#!/usr/bin/perl -w

$ENV{LC_ALL} = "C";

$gontc = "../gontc";
$gontc = $ENV{GONTC} if defined $ENV{GONTC};

sub fail($) {
  print "\n$_[0]\n";
  exit 1;
}

sub parse_file($) {
  my $file = shift;

  $try_run = "";
  $expected_output = "";
  $expected_status = "";

  open(GREPF, "< $file");
  while (<GREPF>) {
    chomp;
    /expected-output:\s*(.*)$/ and $expected_output .= "$1\n";
    /expected-build-status:\s*([a-z]*)/ and $expected_status .= $1;
    /run-test:\s*(.*)$/ and $try_run .= $1;
  }
  close(GREPF);

  fail "$file: does not contain proper expected-build-status: tag"
    unless ($expected_status eq "ok" or
            $expected_status eq "fail" or
            $expected_status eq "warn");

  fail "$file: does not contain proper try-run: tag" 
    unless ($expected_status eq "fail" or
            $try_run eq "yes" or
	    $try_run eq "no");
	    
  return 0;
}

sub run ($) {
    my $f = shift;
    return system("$f") / 256;
}

sub try_run ($) {
  my $f = shift;
  
  print ".";
  
  if ($try_run eq "yes") {
    my $go = $f;
    $go =~ s/\.g/.xgo/;
    $go =~ s|.*/||;
    if (run("$gontc $go -o test-result") == 0) {
      print ".";
      $res = qx"./test-result 2>&1";
      if ($res ne $expected_output) {
        print <<EOF
Expected output:
#v+
$expected_output
#v-

Got:
#v+
$res
#v-
EOF
       ;fail "$f produced evil output"
      }
    } else {
       fail "$f failed to link"
    }
  }
}

#$| = 1;

foreach (@ARGV) {
  my $f = $_;
  print "testing $f ";
  my $iface = $f;
  $iface =~ s/\.g/.gi/;
  if (! -f $iface) {
    open(IFACE, "> $iface");
    print IFACE "/* Autogenerated empty interface for $f */";
    close(IFACE);
    if (run("$gontc -c $iface") != 0) {
      unlink($iface);
      fail "cannot compile interface!";
    }
    unlink($iface);
  } else {
    if (run("$gontc -c $iface") != 0) {
      fail "cannot compile interface!";
    }
  }

  parse_file($f);
  print ".";

  if ($expected_status eq "fail") {
    if (run("$gontc -S $f 2> /dev/null") == 0) {
      fail "unexpected success: $f"
    }
  } elsif ($expected_status eq "ok") {
    if (run("$gontc -c $f") == 0) {
      try_run($f)
    } else {
      fail "unexpected compilation failure: $f"
    }
  } elsif ($expected_status eq "warn") {
    if (run("$gontc -Werror -S $f 2> /dev/null") == 0) {
      fail "didn't get expected warning: $f"
    } else {
      print ".";
      if (run("$gontc -c $f 2> /dev/null") == 0) {
        try_run($f)
      } else {
        fail "got error instead of warning: $f"
      }
    }
  } else { die }
  
  print " done\n";
}  

system("rm -f *.o *.xg* *.ksi test-result");

exit(0);
