1b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#!/usr/bin/env perl
2b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovuse strict;
3b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovuse warnings;
4b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
5b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov######################################################
6b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Binary search script for switchback
7b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Finds bad basic block for seg faults and bad output.
8b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#
9b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# To test output, you need to create test_ref
10b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# test_ref should hold the correct output for running the test_xxx program:
11b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  - Everything between (not including) /^---START---$/ and /^---STOP---$/
12b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  - But NOT including output from /^---begin SWITCHBACK/
13b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#    to /^---  end SWITCHBACK/ inclusive
14b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#
15b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# This script can't handle other vex output,
16b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# so e.g switchback.c::DEBUG_TRACE_FLAGS should be 0
17b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#
18b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
19b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov######################################################
20b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Global consts, vars
21b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovuse constant DEBUG => 0;
22b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovuse constant CONST_N_MAX => 10000000000;
23b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovuse constant CONST_N_MUL => 2;
24b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
25b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $SWITCHBACK = "./switchback";
26b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $N_START = 0;
27b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $N_LAST_GOOD = 0;
28b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $N_LAST_BAD = -1;
29b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $GIVEN_LAST_GOOD = -1;
30b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $GIVEN_LAST_BAD = -1;
31b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $TEST_REF;
32b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
33b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
34b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
35b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov######################################################
36b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Helper functions
37b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
38b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovsub Exit {
39b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    exit $_[0];
40b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
41b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
42b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovsub Usage {
43b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "Usage: binary_switchback.pl test_ref [last_good [last_bad]]\n";
44b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "where:\n";
45b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "   test_ref  = reference output from test_xxx\n";
46b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "   last_good = last known good bb (search space minimum)\n";
47b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "   last_bad  = last known bad bb (search space maximum)\n";
48b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "\n";
49b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
50b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
51b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovsub QuitUsage {
52b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print $_[0]."\n";
53b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    Usage();
54b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    Exit 1;
55b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
56b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
57b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
58b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov######################################################
59b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Get & check cmdline args
60b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# - if given, override global vars.
61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
62b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif (@ARGV < 1 || @ARGV > 3) {
63b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    QuitUsage "Error: Bad num args\n";
64b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
65b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
66b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov$TEST_REF = $ARGV[0];
67b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
68b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif ( ! -x "$SWITCHBACK" ) {
69b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    QuitUsage "File doesn't exist | not executable: '$SWITCHBACK'\n";
70b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
71b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
72b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif (@ARGV >1) {
73b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    $N_LAST_GOOD = $ARGV[1];
74b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    $GIVEN_LAST_GOOD = $N_LAST_GOOD;
75b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if (! ($N_LAST_GOOD =~ /^\d*$/)) {
76b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	QuitUsage "Error: bad arg for #last_good\n";
77b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
78b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if ($N_LAST_GOOD >= CONST_N_MAX) {
79b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	QuitUsage "Error: #last_good >= N_MAX(".CONST_N_MAX.")\n";
80b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
81b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
82b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif (@ARGV >2) {
83b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    $N_LAST_BAD = $ARGV[2];
84b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    $GIVEN_LAST_BAD = $N_LAST_BAD;
85b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if (! ($N_LAST_BAD =~ /^\d*$/)) {
86b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	QuitUsage "Error: bad arg for 'last_bad'\n";
87b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
88b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
89b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
90b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Setup N_START
91b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif ($N_LAST_BAD != -1) {
92b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    # Start halfway:
93b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    my $diff = $N_LAST_BAD - $N_LAST_GOOD;
94b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    $N_START = $N_LAST_GOOD + ($diff - ($diff % 2)) / 2;
95b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} else {
96b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    # No known end: Start at beginning:
97b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if ($N_LAST_GOOD > 0) {   # User-given last_good
98b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	$N_START = $N_LAST_GOOD;
99b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    } else {
100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	$N_START = 100;       # Some reasonable number.
101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
103b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov######################################################
105b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Sanity checks (shouldn't ever happen)
106b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif ($N_START < $N_LAST_GOOD) {
108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "Program Error: start < last_good\n";
109b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    exit 1;
110b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
111b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif ($N_LAST_BAD != -1 && $N_START >= $N_LAST_BAD) {
112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "Program Error: start >= last_bad\n";
113b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    exit 1;
114b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif ($N_START < 1 || $N_START > CONST_N_MAX) {
116b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "Program Error: Bad N_START: '$N_START'\n";
117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    exit 1;
118b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif ($N_LAST_GOOD < 0 || $N_LAST_GOOD > CONST_N_MAX) {
120b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "Program Error: Bad N_LAST_GOOD: '$N_LAST_GOOD'\n";
121b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    exit 1;
122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif ($N_LAST_BAD < -1 || $N_LAST_BAD > CONST_N_MAX) {
124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "Program Error: Bad N_LAST_BAD: '$N_LAST_BAD'\n";
125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    exit 1;
126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov######################################################
134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Helper functions
135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Run switchback for test, for N bbs
137b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# returns output results
138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovsub SwitchBack {
139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    my $n = $_[0];
140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if ($n < 0 || $n > CONST_N_MAX) {
141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	print "Error SwitchBack: Bad N: '$n'\n";
142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	Exit 1;
143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
144b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    my $TMPFILE = ".switchback_output.$n";
145b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
146b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "=== Calling switchback for bb $n ===\n";
147b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
148b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    system("$SWITCHBACK $n >& $TMPFILE");
149b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    my $ret = $?;
150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
151b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if ($ret == 256) {
152b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	print "Error running switchback - Quitting...\n---\n";
153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	open(INFILE, "$TMPFILE");
154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	print <INFILE>;
155b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	close(INFILE);
156b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
157b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	unlink($TMPFILE) if (! DEBUG);
158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	exit 0;
159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if ($ret & 127) {
162b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	print "Ctrl-C pressed - Quitting...\n";
163b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	unlink($TMPFILE) if (! DEBUG);
164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	exit 0;
165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if (DEBUG) {
168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	if ($ret == -1) {
169b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    print "failed to execute: $!\n";
170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	}
171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	elsif ($ret & 127) {
172b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    printf "child died with signal %d, %s coredump\n",
173b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ($ret & 127),  ($ret & 128) ? 'with' : 'without';
174b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	}
175b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	else {
176b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    printf "child exited with value %d\n", $ret >> 8;
177b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	}
178b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
179b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if ($ret != 0) { # Err: maybe seg fault
180b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	open(INFILE, "$TMPFILE");
181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	my @results = <INFILE>;
182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	close(INFILE);
183b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
184b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	while (@results && !((shift @results) =~ /^---START---/)) {}
185b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	print @results;
186b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
187b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	unlink($TMPFILE) if (! DEBUG);
188b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	return;
189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
190b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
191b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    open(INFILE, "$TMPFILE");
192b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    my @results = <INFILE>;
193b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    close(INFILE);
194b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
195b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    unlink($TMPFILE) if (! DEBUG);
196b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    return @results;
197b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
198b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
199b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Returns N simulated bbs from output lines
200b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovsub get_N_simulated {
201b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    my @lines = @{$_[0]};
202b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    pop @lines;             # not the first...
203b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    my $line = pop @lines;  # ...but the second line.
204b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
205b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    chomp $line;
206b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    my $n;
207b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if (($n) = ($line =~ /^(\d*) bbs simulated$/)) {
208b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	return $n;
209b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
210b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "Error: Didn't find N bbs simultated, from output lines\n";
211b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    Exit 1;
212b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
213b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
214b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Calls test script to compare current output lines with a reference.
215b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Returns 1 on success, 0 on failure
216b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovsub TestOutput {
217b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    my @lines = @{$_[0]};
218b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    my $n = $_[1];
219b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    my $ref_output = "$TEST_REF";
220b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
221b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    # Get the current section we want to compare:
222b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    my @newlines;
223b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    my $ok=0;
224b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    my $halfline = "";
225b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    foreach my $line(@lines) {
226b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	chomp $line;
227b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	if ($line =~ /^---STOP---$/) { last; }     # we're done
228b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
229b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	# output might be messed up here...
230b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	if ($line =~ /^.*---begin SWITCHBACK/) {
231b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    ($halfline) = ($line =~ /^(.*)---begin SWITCHBACK/);
232b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    $ok = 0;  # stop on prev line
233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	}
234b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
235b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	# A valid line:
236b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	if ($ok) {
237b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    if ($halfline ne "") {   # Fix broken line
238b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov		$line = $halfline.$line;
239b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov		$halfline = "";
240b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    }
241b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
242b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    # Ignore Vex output
243b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    if ($line =~ /^vex /) { next; }
244b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
245b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    push(@newlines, $line);
246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	}
247b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
248b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	if ($line =~ /^---START---$/) {            # start on next line
249b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    $ok = 1;
250b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	}
251b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
252b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	if ($line =~ /^---  end SWITCHBACK/) {     # start on next line
253b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    $ok = 1;
254b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
255b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	}
256b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
257b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
258b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if (DEBUG) {
259b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	open(OUTFILE, ">.filtered_output.$n");
260b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	print OUTFILE join("\n",@newlines);
261b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	close(OUTFILE);
262b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
263b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
264b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    # Read in reference lines
265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    open(REFERENCE, "$ref_output") || die "Error: Couldn't open $ref_output\n";
266b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    my @ref_lines = <REFERENCE>;
267b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    close(REFERENCE);
268b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
269b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    # Compare reference lines with current:
270b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    my $match = 1;
271b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    my $i = 0;
272b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    foreach my $ref_line(@ref_lines) {
273b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	chomp $ref_line;
274b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	my $line = $newlines[$i++];
275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	chomp $line;
276b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	if ($ref_line ne $line) {
277b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    print "\nMismatch on output:\n";
278b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    print "ref: '$ref_line'\n";
279b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    print "new: '$line'\n\n";
280b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    $match = 0;
281b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    last;
282b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	}
283b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
284b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    return $match;
285b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
286b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
287b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
288b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
289b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
290b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
291b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
292b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov######################################################
293b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Do the search
294b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
295b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif (DEBUG) {
296b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "\n------------\n";
297b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "START:  N=$N_START\n";
298b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "START: lg=$N_LAST_GOOD\n";
299b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "START: lb=$N_LAST_BAD\n";
300b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "START: GIVEN_LAST_GOOD=$GIVEN_LAST_GOOD\n";
301b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "START: GIVEN_LAST_BAD =$GIVEN_LAST_BAD\n";
302b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "\n";
303b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
304b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
305b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $N = $N_START;
306b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $success = 0;
307b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy @sb_output;
308b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovwhile (1) {
309b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if (DEBUG) {
310b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	print "\n------------\n";
311b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	print "SOL: lg=$N_LAST_GOOD\n";
312b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	print "SOL: lb=$N_LAST_BAD\n";
313b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	print "SOL:  N=$N\n";
314b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
315b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if ($N < 0) {
316b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	print "Error: $N<0\n";
317b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	Exit 1;
318b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
319b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
320b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    my $ok = 1;
321b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    # Run switchback:
322b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    @sb_output = SwitchBack($N);
323b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
324b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if (@sb_output == 0) { # Switchback failed - maybe seg fault
325b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	$ok = 0;
326b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
327b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
328b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if (DEBUG) {
329b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	open(fileOUT, ">.retrieved_output.$N") or die("Can't open file for writing: $!");
330b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	print fileOUT @sb_output;
331b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	close(fileOUT);
332b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
333b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
334b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    # If we're ok so far (no seg faults) then test for correct output
335b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if ($ok) {
336b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	$ok = TestOutput( \@sb_output, $N );
337b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
338b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
339b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if ($ok) {
340b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	if (get_N_simulated(\@sb_output) < $N) { # Done: No bad bbs
341b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    $success = 1;
342b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    last;
343b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	}
344b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	if ($N_LAST_BAD == -1) {
345b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    # No upper bound for search space
346b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    # Try again with a bigger N
347b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
348b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    $N_LAST_GOOD = $N;
349b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    $N *= CONST_N_MUL;
350b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    if ($N > CONST_N_MAX) {
351b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov		print "\nError: Maxed out N($N): N_MAX=".CONST_N_MAX."\n";
352b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov		print "\nWe're either in a loop, or this is a big test program (increase N_MAX)\n\n";
353b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov		Exit 1;
354b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    }
355b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    if (DEBUG) {
356b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov		print "Looks good so far: Trying bigger N...\n\n";
357b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    }
358b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    next;
359b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	}
360b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
361b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
362b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    # Narrow the search space:
363b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if ($ok) { $N_LAST_GOOD = $N; }
364b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    else {     $N_LAST_BAD  = $N;  }
365b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
366b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    # Calculate next step:
367b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    my $diff = $N_LAST_BAD - $N_LAST_GOOD;
368b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    $diff = $diff - ($diff % 2);
369b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    my $step = $diff / 2;
370b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
371b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if ($step < 0) {
372b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	print "Error: step = $step\n";
373b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	Exit 1;
374b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
375b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
376b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    # This our last run-through?
377b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if ($step!=0) {
378b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	$N = $N_LAST_GOOD + $step;   # Keep on going...
379b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    } else {
380b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	last;                        # Get outta here
381b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
382b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
383b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if (DEBUG) {
384b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	print "\nEOL: ok=$ok\n";
385b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	print "EOL: lg=$N_LAST_GOOD\n";
386b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	print "EOL: lb=$N_LAST_BAD\n";
387b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	print "EOL:  s=$step\n";
388b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	print "EOL:  N=$N\n";
389b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
390b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
391b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
392b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
393b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
394b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov######################################################
395b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Done: Report results
396b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
397b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovprint "\n============================================\n";
398b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovprint "Done searching.\n\n";
399b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
400b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif ($N_LAST_BAD != -1 && $N != $N_LAST_BAD) {
401b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "Getting output for last bad bb:\n";
402b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    @sb_output = SwitchBack($N_LAST_BAD);
403b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
404b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
405b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovprint @sb_output;
406b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovprint "\n\n";
407b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif ($success) {
408b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "*** Success!  No bad bbs found. ***\n";
409b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} else {
410b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if ($N_LAST_BAD == $GIVEN_LAST_BAD) {
411b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	print "*** No failures detected within given bb range ***\n";
412b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	print " - check given 'last_bad' argument\n";
413b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    } else {
414b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	if ($N_LAST_BAD == $GIVEN_LAST_GOOD) {
415b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    print "*** Failed on bb given as last_good ***\n";
416b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    print " - decrease the 'last_good' argument\n";
417b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	} else {
418b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    print "*** Failure: Last failed switchback bb: $N_LAST_BAD ***\n";
419b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    print "Hence bad bb: ". ($N_LAST_BAD - 1) ."\n";
420b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	}
421b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
422b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
423b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovprint "\n";
424b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif (DEBUG) {
425b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "END:  N=$N\n";
426b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "END: lg=$N_LAST_GOOD\n";
427b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "END: lb=$N_LAST_BAD\n";
428b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "END: GIVEN_LAST_BAD=$GIVEN_LAST_BAD\n";
429b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    print "\n";
430b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
431b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovExit 0;
432