- my $file = basename($candidate, '.out');
- (my $name = $file =~ s/^[^-]*-//r) =~ tr/_/ /;
- my $todo = $name =~ s/ #TODO$//;
+ my $name = basename($candidate, '.out');
+ $name =~ tr/_/ /;
+ local $TODO;
+
+ if (!-e $candidate) {
+ local $TODO = 'missing output';
+ fail($name);
+ next;
+ }
+
+ open my $fh, '<', $candidate or die "missing $candidate: $!\n";
+ !!(my $spec = readline $fh)
+ or die "input lacks a script on the first line\n";
+
+ my $script = $spec;
+ chomp $script;
+ $script =~ s/\h* [#]\h* todo \h* (.*?) \z//i
+ and $TODO = $+ || ' ';
+ my $wantexit = $script =~ s/\h+[?](\d+)\z// ? $1 : 0;
+ my $wantwarn = $script !~ s/[?]\z//;
+
+ my $shell = $script;
+ if ($script =~ /\|/) {
+ # explicit shell wrapper to capture all warnings
+ $shell =~ s/'/'\\''/g;
+ $shell = "sh -c '$shell'";
+ }
+ $shell .= ' 2>' . ($wantwarn ? '&1' : '/dev/null');
+
+ open my $cmd, '-|', $shell or do {
+ fail($name);
+ diag("open failure: $!");
+ diag("command: $script");
+ next;
+ };
+ my @lines = readline $cmd;
+ close $cmd;
+ my $error = $? >> 8;