#!/usr/bin/perl -w
require strict;
use Getopt::Long;

my $token = "X";
my $pass = 0;
my $fail = 1;
my $pat_pass = "";
my $pat_fail = "";
my $width = 1e-10;
GetOptions ("token=s" => \$token, # Token to replace with binary search value
            "pass=f"   => \$pass, # "pass" bound for search interval
            "fail=f"   => \$fail, # "fail" bound for search interval
            "width=f"   => \$width, # interval width to terminate search
            "pat_pass=s"   => \$pat_pass, # regexp identifying pass result
            "pat_fail=s"   => \$pat_fail) # regexp identifying fail result
    or die("Error in command line arguments\n");

($pat_pass || $pat_fail) or die "Must specify stable string or unstable string.";

my $cmd="@ARGV";

while($fail-$pass>$width || $pass-$fail>$width)
{
    my $M=($pass+$fail)/2;
    $_=$cmd;
    s/\b$token\b/$M/g;
    print "cmd: $_\n";
    my $out=`$_`;
    my $ok=($pat_pass && $out=~/$pat_pass/) || ($pat_fail && !($out=~/$pat_fail/));
    if($ok)
    {
        print "PASS\n\n";
        $pass=$M;
    }
    else
    {
        print "FAIL\n\n";
        $fail=$M;
    }
}

print "value: $pass $fail\n";
