#! /usr/bin/perl -w -X
# XqtS <.ccf file> 
#
# Runs a "theory" file with state by table lookup
#
# Messages must go to a log, (xxx.errlog for file xxx.ccf)
#  since any output is intercepted
#
use component;

sub logdie {
# arg is a list of messages
# return all values of 0 and append messages to the file
#
$logf = $base.".errlog";
unless (-e $logf) { #create log file
  open(L,">$logf");
  close(L);
}
open(L,">>$logf");
foreach $m (@_) {
  print L $m;
}
print L "\n";
close(L);


$Y = $R = $Z = 0; #return phony values
goto ALL;
}

$base = "anon";
unless (defined($ARGV[0])) {
  logdie "A .ccf file must be given";
}
$ccf = $ARGV[0];
@fn = split(/\./,$ccf);
$base = $fn[0];
logdie "Parameter file ", $ccf, " must be a .ccf file" unless($fn[1] eq "ccf");
logdie "No 'theory' file to execute" unless(-e $ccf."c");
open(CCFT, $ccf."c");
$thline = <CCFT>;
@hed = split(' ',$thline); #state, 1, isubs, ssubs, initial
$initstate = $hed[4];
$dataskip = $hed[2] + $hed[3];
$numisubs = $hed[2];
close(CCFT);
open(CCF, $ccf) || logdie "given file ",$ccf," not found";

chop($X = <STDIN>);  #read input

#get the input state value

chop($name = <CCF>); #real program name
@nl = split(' ',$name);
$name = $nl[0];
@nl = split('\.',$name);
$ccfState = $nl[0].".state"; #component.pm used program, not .ccf base name
#print "|$ccfState|\n";  #debug
if (open(STF,"<".$ccfState)) {
  $S = <STF>;  #the current state value
  close(STF);
} else {
  $S = $initstate;
  $Y = 0;
  $R = 0;
  $Z = $S;
  goto ALL;
}

$iline = 0; 
$found = 0;
IL: while ($line = <CCF>) {
  if ($line eq "\n") {  #blank line, end of input subdomains
    last IL;
  }
  @vals = split(" ",$line);
  if ($X >= $vals[0] && $X < $vals[1]) { #in this input subdomain
    $found = 1;
    last IL;
  }
  $iline++;
}
logdie "input ",$X," out of subdomain range" unless ($found);
#skip past blank line
SI: while (chop($line = <CCF>)) {
  if ($line eq "") {
    last SI;
  }
}
$sline = 0;  
$found = 0;
SL: while ($line = <CCF>) {
  @vals = split(" ",$line);
  if ($S >= $vals[0] && $S < $vals[1]) { #in this state subdomain
    $found = 1;
    last SL;
  }
  $sline++;
}
logdie "state ",$S," out of subdomain range" unless ($found);
close(CCF);

open(CCFT, "<".$ccf."c"); #checked for existence above

#skip to data line
$dataskip += 2 + $sline*$numisubs + $iline;
for ($r=0; $r<$dataskip; $r++) { #skip down to correct data line
  $line = <CCFT>; 
}
@vals = split(" ",$line); #format:  N out run state 3 errors
$N = $vals[0];
$Y = $vals[1];
$R = $vals[2];
$Z = $vals[3];
close(CCFT);
logdie "No test information for subdomain holding (",$X,",",$S,")" unless ($N != 0);

ALL:
print "$Y\n"; #functional value
printf STDERR "$R\n"; #run time
open(STF,">".$ccfState); #can't print anything if it fails...
print STF "$Z"; #state value 
close(STF);
