use Getopt::Long qw(GetOptions);
use strict;
-use Term::ANSIColor;
use Text::ParseWords;
use IPC::Open3;
use IO::File;
}
##
-## Command line option handling
+## Helper functions
##
-if ( $ARGV[0] eq "--internal-killer-process" ) {
-
- # We fork+exec a waiter process in charge of killing the command after timeout
- # If the command stops earlier, that's fine: the killer sends a signal to an already stopped process, fails, and quits.
- # Nobody cares about the killer issues.
- # The only problem could arise if another process is given the same PID than cmd. We bet it won't happen :)
- my $time_to_wait = $ARGV[1];
- my $pid = $ARGV[2];
- sleep $time_to_wait;
- kill( 'TERM', $pid );
- sleep 1;
- kill( 'KILL', $pid );
- exit $time_to_wait;
-}
-
+# Helper function replacing any occurence of variable '$name' by its '$value'
+# As in Bash, ${$value:=BLABLA} is rewritten to $value if set or to BLABLA if $value is not set
sub var_subst {
my ( $text, $name, $value ) = @_;
if ($value) {
return $text;
}
-# option handling helper subs
+# Command CD. Just change to the provided directory
sub cd_cmd {
- my $directory = $_[1];
+ my $directory = shift;
my $failure = 1;
if ( -e $directory && -d $directory ) {
chdir("$directory");
}
}
+# Command setenv. Gets "variable=content", and update the environment accordingly
sub setenv_cmd {
- my ( $var, $ctn );
- if ( $_[0] =~ /^(.*)=(.*)$/ ) {
- ( $var, $ctn ) = ( $1, $2 );
- } elsif ( $_[1] =~ /^(.*)=(.*)$/ ) {
- ( $var, $ctn ) = ( $1, $2 );
+ my $arg = shift;
+ if ( $arg =~ /^(.*)=(.*)$/ ) {
+ my ( $var, $ctn ) = ( $1, $2 );
+ print "[Tesh/INFO] setenv $var=$ctn\n";
+ $environ{$var} = $ctn;
} else {
- die "[Tesh/CRITICAL] Malformed argument to setenv: expected 'name=value' but got '$_[1]'\n";
+ die "[Tesh/CRITICAL] Malformed argument to setenv: expected 'name=value' but got '$arg'\n";
}
-
- print "[Tesh/INFO] setenv $var=$ctn\n";
- $environ{$var} = $ctn;
}
-# Main option parsing sub
+##
+## Command line option handling
+##
-sub get_options {
+if ( $ARGV[0] eq "--internal-killer-process" ) {
- # remove the tesh file from the ARGV used
- my @ARGV = @_;
- $tesh_file = pop @ARGV;
+ # We fork+exec a waiter process in charge of killing the command after timeout
+ # If the command stops earlier, that's fine: the killer sends a signal to an already stopped process, fails, and quits.
+ # Nobody cares about the killer issues.
+ # The only problem could arise if another process is given the same PID than cmd. We bet it won't happen :)
+ my $time_to_wait = $ARGV[1];
+ my $pid = $ARGV[2];
+ sleep $time_to_wait;
+ kill( 'TERM', $pid );
+ sleep 1;
+ kill( 'KILL', $pid );
+ exit $time_to_wait;
+}
+
+sub get_options {
# temporary arrays for GetOption
my @cfg;
'difftool=s' => \$diff_tool,
- 'cd=s' => \&cd_cmd,
+ 'cd=s' => sub { cd_cmd($_[1]) },
'timeout=s' => \$opt{'timeout'},
- 'setenv=s' => \&setenv_cmd,
+ 'setenv=s' => sub { setenv_cmd($_[1]) },
'cfg=s' => \@cfg,
'log=s' => \$log,
'enable-coverage+' => \$enable_coverage,
);
+ $tesh_file = pop @ARGV;
+
if ($enable_coverage) {
print "Enable coverage\n";
}
return %opt;
}
-my %opts = get_options(@ARGV);
+my %opts = get_options();
##
## File parsing
###
# exec the command line
- ### $line =~ s/\r//g;
$cmd{'got'} = IO::File->new_tmpfile;
$cmd{'got'}->autoflush(1);
if ( $cmd{'background'} != 1 ) {
waitpid( $cmd{'pid'}, 0 );
$cmd{'gotret'} = exit_status($?);
- parse_out( \%cmd );
+ parse_result( \%cmd );
} else {
# & commands, which will be handled at the end
}
}
-sub parse_out {
+sub parse_result {
my %cmd = %{ $_[0] };
my $gotret = $cmd{'gotret'};
if scalar @{ cmd { 'out' } };
$arg =~ s/^ *cd //;
- cd_cmd( "", $arg );
+ cd_cmd( $arg );
%cmd = ();
} else { # regular command
$cmd{'file'} = $tesh_file;
$cmd{'line'} = $line_num;
}
- } elsif ( $cmd eq '&' ) { # parallel command line
+ } elsif ( $cmd eq '&' ) { # background command line
if ( defined( $cmd{'cmd'} ) ) {
exec_cmd( \%cmd );
$cmd{'cmd'} = $arg;
$cmd{'file'} = $tesh_file;
$cmd{'line'} = $line_num;
+
} elsif ( $line =~ /^!\s*output sort/ ) { #output sort
if ( defined( $cmd{'cmd'} ) ) {
exec_cmd( \%cmd );
$line =~ s/^! setenv //g;
$line =~ s/\r//g;
setenv_cmd($line);
- } elsif ( $line =~ /^!\s*include/ ) { #include
- if ( defined( $cmd{'cmd'} ) ) {
- exec_cmd( \%cmd );
- %cmd = ();
- }
- print color("red"), "[Tesh/CRITICAL] need include";
- print color("reset"), "\n";
- die;
} elsif ( $line =~ /^!\s*timeout/ ) { #timeout
if ( defined( $cmd{'cmd'} ) ) {
exec_cmd( \%cmd );
my %test = %{$_};
waitpid( $test{'pid'}, 0 );
$test{'gotret'} = exit_status($?);
- parse_out( \%test );
+ parse_result( \%test );
}
@bg_cmds = ();