2 eval 'exec perl -S $0 ${1+"$@"}'
3 if $running_under_some_shell;
13 B<tesh> [I<options>] I<tesh_file>
17 use Pod::Usage qw(pod2usage);
18 use Getopt::Long qw(GetOptions);
24 # make sure we received a tesh file
25 scalar @ARGV > 0 || pod2usage(-exitval => 1);
27 #Add current directory to path
28 $ENV{PATH} = "$ENV{PATH}:.";
32 ## Command line option handling
35 # option handling helper subs
40 print "[Tesh/INFO] change directory to $directory\n";
42 die "[Tesh/CRITICAL] Directory not found : \"$directory\"\n";
47 if ($_[1] =~ /^(.*)=(.*)$/) {
48 my($var,$ctn)=($1,$2);
50 print "[Tesh/INFO] setenv $var=$ctn\n";
52 die "[Tesh/CRITICAL] Malformed argument to setenv: expected 'name=value' but got '$_[1]'\n";
56 # Main option parsing sub
59 # remove the tesh file from the ARGV used
61 $tesh_file = pop @ARGV;
63 # temporary arrays for GetOption
73 Getopt::Long::config('bundling', 'no_getopt_compat', 'no_auto_abbrev');
76 'help|h' => \$opt{'help'},
78 'verbose|v' => \@verbose,
79 'debug|d' => \$opt{"debug"},
82 'setenv=s' => \&setenv_cmd,
86 $opt{'verbose'} = scalar @verbose;
88 $opt{'cfg'} .= " --cfg=$_";
93 my %opts = get_options(@ARGV);
98 my($line2,$execline,$command,$command_tesh);
99 my($command_executed)=0;
100 my($expected_result_line)=0;
103 my(@list1,@list2,@list3,@list_of_commands)=();
110 my($no_output_ignore)=1;
124 open TESH_FILE, $tesh_file or die "[Tesh/CRITICAL] Unable to open $tesh_file $!\n";
126 my %cmd; # everything about the next command to run
127 while (defined(my $line1=<TESH_FILE>)) {
129 if($line1 =~ /^\< \$ /){ # arg command line
130 $line1 =~ s/\${EXEEXT:=}//g;
131 $line1 =~ s/^\< \$\ *//g;
132 $line1 =~ s|^./lua|lua|g;
133 $line1 =~ s|^./ruby|ruby|g;
135 $line1 =~ s|^tesh|./tesh|g;
136 $line1 =~ s/\(%i:%P@%h\)/\\\(%i:%P@%h\\\)/g;
137 $command_tesh = $line1;
138 print "[Tesh/INFO] arg_exec_line : $command_tesh\n";
140 elsif($line1 =~ /^\< \< /){ # arg buffer line
141 $line1 =~ s/^\< \<\ *//g;
142 print "[Tesh/INFO] arg_buffer_line : $line1\n";
143 push @buffer_tesh, "$line1\n";
145 elsif($line1 =~ /^\< \> /){ # arg output line
146 $line1 =~ s/^\< \>\ *//g;
149 print "[Tesh/INFO] arg_output_line : $line1\n";
150 $expected_result_line = 1;
152 elsif($line1 =~ /^\$ mkfile/){ # "mkfile" command line
154 $line1 =~ s/mkfile//g;
157 print "[Tesh/INFO] exec_line : mkfile $fich_name\n";
159 open(FILE,">$fich_name") or die "[Tesh/CRITICAL] Unable to make file : $fich_name. $!\n";
164 elsif($line1 =~ /^\$ cd/){ # "cd" command line
166 print "[Tesh/INFO] exec_line : $line1\n";
168 chdir("$line1") or die "[Tesh/CRITICAL] Unable to open $line1. $!\n";
170 elsif($line1 =~ /^\$ /){ #command line
171 if($line1 =~ m|^\$ ./tesh|){ # tesh command line
173 @buffer = @buffer_tesh;
176 $line1 =~ s/\${EXEEXT:=}//g;
177 $line1 =~ s/^\$\ *//g;
178 $line1 =~ s|^./lua|lua|g;
179 $line1 =~ s|^./ruby|ruby|g;
181 $line1 =~ s|^tesh|./tesh|g;
182 $line1 =~ s/\(%i:%P@%h\)/\\\(%i:%P@%h\\\)/g;
183 $line1 = "$line1 $config";
187 print "[Tesh/CRITICAL] -\n";
188 print "[Tesh/CRITICAL] + @list1";
189 print color("reset"), "\n";
191 if(@list_of_commands){ # need parallel execution
192 push @list_of_commands, $line1;
193 print "[Tesh/INFO] exec_line : $line1\n";
196 print "[Tesh/INFO] exec_line : $line1\n";
198 { $execline = $command_tesh;
201 { $execline = $line1;}
202 $pid = open3(\*IN, \*OUT, \*OUT, $execline );
204 $forked = fork();die "fork() failed: $!" unless defined $forked;
215 $line1 = shift (@buffer);
221 if($timeout){kill(9, $forked);$timeout=0;}
224 while(defined($linebis=<OUT>))
227 $linebis =~ s/^( )*//g;
229 push @list1,"$linebis";
232 $command_executed = 1;
235 elsif($line1 =~ /^\& /){ # parallel command line
236 $command_executed = 0;
237 $expected_result_line = 0;
238 $line1 =~ s/\${EXEEXT:=}//g;
240 $line1 =~ s|^./lua|lua|g;
241 $line1 =~ s|^./ruby|ruby|g;
243 $line1 =~ s/\(%i:%P@%h\)/\\\(%i:%P@%h\\\)/g;
244 $line1 = "$line1 $config";
246 $execline = "$line1";
247 print "[Tesh/INFO] exec_line : $execline\n";
248 push @list_of_commands, $execline;
250 elsif($line1 =~ /^\>/){ #expected result line
251 $line1 =~ s/^\>( )*//g;
254 $expected_result_line = 1;
256 elsif($line1 =~ /^\</ or $encore==1){ #need to buffer
257 $line1 =~ s/^\<( )*//g; #delete < with space or tab after
259 if($line1 =~ /\\$/) # need to store this line into old_buff
263 $old_buffer = "$old_buffer$line1";
267 if($encore == 1){push @buffer, "$old_buffer$line1";}
268 else{push @buffer, "$line1\n";}
273 elsif($line1 =~ /^p/){ #comment
276 print "[Tesh/INFO] comment_line :$line1\n";
278 elsif($line1 =~ /^! output sort/){ #output sort
281 elsif($line1 =~ /^! output ignore/){ #output ignore
284 elsif($line1 =~ /^! expect signal SIGABRT$/) #expect signal SIGABRT
288 elsif($line1 =~ /^! expect return/){ #expect return
289 $line1 =~ s/^! expect return //g;
292 print color("red"), "[Tesh/INFO] expect return $return";
293 print color("reset"), "\n";
296 elsif($line1 =~ /^! setenv/){ #setenv
297 $line1 =~ s/^! setenv //g;
299 $line1 =~ /^(.*)=(.*)$/;
301 print "[Tesh/INFO] setenv: $1=$2\n";
303 elsif($line1 =~ /^! include/){ #output sort
304 print color("red"), "[Tesh/CRITICAL] need include";
305 print color("reset"), "\n";
308 elsif($line1 =~ /^! timeout/){ #timeout
309 $line1 =~ s/^! timeout //g;
311 if($timeout != $line1){
313 print "[Tesh/INFO] timeout : $timeout\n";}
315 elsif($line1 =~ /^! need execute/){ #need execute // commands
317 $sort = 1; # need sort output
318 while(@list_of_commands)
320 $command = shift (@list_of_commands);
321 if($execline){$execline = "$command & $execline";}
322 else{$execline = "$command";}
324 $pid = open3(\*IN, \*OUT, \*OUT, $execline);
326 $forked = fork();die "fork() failed: $!" unless defined $forked;
337 $line1 = shift (@buffer);
342 if($timeout){kill(9, $forked);$timeout=0;}
346 while(defined($linebis=<OUT>))
349 $linebis =~ s/^( )*//g;
351 push @list1,"$linebis";
354 $command_executed = 1;
356 elsif($command_executed and $expected_result_line)
358 if($no_output_ignore){
362 @list3 = sort @list1;
367 @list3 = sort @list2;
376 push @list2,"Aborted";
380 while(@list1 or @list2)
382 if(@list1){$line1 = shift (@list1);$expected_result_line = "x$line1";}
383 if(@list2){$line2 = shift (@list2);$command_executed = "x$line2";}
384 if($command_executed and $expected_result_line)
387 if($line1 eq $line2){
388 if($verbose == 1){print color("green"),"[Tesh/VERB] $line1\n",color("reset");}
389 else{push @buffer, "[Tesh/CRITICAL] $line1\n";}
393 { if($verbose == 0){print color("green"),@buffer,color("reset");}
394 if($line2) {print color("red"), "[Tesh/CRITICAL] - $line2",color("reset"),"\n";}
395 if($line1) {print color("red"), "[Tesh/CRITICAL] + $line1",color("reset"),"\n";}
400 { if($verbose == 0){print color("green"),@buffer,color("reset");}
401 if($line2) {print color("red"), "[Tesh/CRITICAL] - $line2",color("reset"),"\n";}
402 if($line1) {print color("red"), "[Tesh/CRITICAL] + $line1",color("reset"),"\n";}
406 }else{$no_output_ignore = 1;}
407 $command_executed = 0;
408 $expected_result_line = 0;
418 if(@list_of_commands){ # need parallel execution
420 $sort = 1; # need sort output
421 while(@list_of_commands)
423 $command = shift (@list_of_commands);
424 if($execline){$execline = "$command & $execline";}
425 else{$execline = "$command";}
427 print "[Tesh/INFO] exec_line : $execline\n";
428 $pid = open3(\*IN, \*OUT, \*OUT,"$execline");
431 $forked = fork();die "fork() failed: $!" unless defined $forked;
442 $line1 = shift (@buffer);
447 if($timeout){kill(9, $forked);$timeout=0;}
451 while(defined($linebis=<OUT>))
454 $linebis =~ s/^( )*//g;
456 push @list1,"$linebis";
459 $command_executed = 1;
462 if($command_executed and $expected_result_line ){
463 if($no_output_ignore){
467 @list3 = sort @list1;
472 @list3 = sort @list2;
481 push @list2,"Aborted";
485 while(@list1 or @list2)
487 if(@list1){$line1 = shift (@list1);$expected_result_line = "x$line1";}
488 if(@list2){$line2 = shift (@list2);$command_executed = "x$line2";}
489 if($command_executed and $expected_result_line)
491 if($line1 eq $line2){
492 if($verbose == 1){print color("green"),"[Tesh/VERB] $line1\n",color("reset");}
493 else{push @buffer, "[Tesh/CRITICAL] $line1\n";}
497 { if($verbose == 0){print color("green"),@buffer,color("reset");}
498 if($line2) {print color("red"), "[Tesh/CRITICAL] - $line2",color("reset"),"\n";}
499 if($line1) {print color("red"), "[Tesh/CRITICAL] + $line1",color("reset"),"\n";}
504 { if($verbose == 0){print color("green"),@buffer,color("reset");}
505 if($line2) {print color("red"), "[Tesh/CRITICAL] - $line2",color("reset"),"\n";}
506 if($line1) {print color("red"), "[Tesh/CRITICAL] + $line1",color("reset"),"\n";}
510 }else{$no_output_ignore = 1;}
511 $command_executed = 0;
512 $expected_result_line= 0;