|  | #!/usr/bin/env perl | 
|  |  | 
|  | # runtest [options] FILENAME | 
|  | # | 
|  | # Read the file FILENAME. Each line contains a test. | 
|  | # Convert template to test and crosstest. | 
|  | # If possilble generate orphaned testversions, too. | 
|  | # Use make to compile the test | 
|  |  | 
|  | ################################################################################ | 
|  | # Global configuration options for the runtestscript itself: | 
|  | ################################################################################ | 
|  |  | 
|  | # name of the global configuration file for the testsuite: | 
|  | $config_file    = "ompts.conf"; | 
|  | $logfile        = "ompts.log"; # overwriteable by value in config file | 
|  | $env_set_threads_command = 'OMP_NUM_THREADS=%n; export OMP_NUM_THREADS;'; | 
|  | $debug_mode     = 0; | 
|  | ################################################################################ | 
|  | # After this line the script part begins! Do not edit anithing below | 
|  | ################################################################################ | 
|  |  | 
|  |  | 
|  | # Namespaces: | 
|  | use Getopt::Long; | 
|  | #use Unix::PID; | 
|  | use Data::Dumper; | 
|  | use ompts_parserFunctions; | 
|  |  | 
|  | # Extracting given options | 
|  | GetOptions("help", | 
|  | "listlanguages", | 
|  | "lang=s", | 
|  | "list", | 
|  | "testinfo=s", | 
|  | "numthreads=i", | 
|  | "test=s", | 
|  | "compile!", | 
|  | "run!", | 
|  | "orphan!", | 
|  | "resultfile=s" | 
|  | ); | 
|  |  | 
|  | # Get global configuratino options from config file: | 
|  | if(! -e $config_file){ error ("Could not find config file $config_file\n", 1);} | 
|  | open (CONFIG, "<$config_file") or error ("Could not open config file $config_file\n", 2); | 
|  | while (<CONFIG>) { $config .= $_; } | 
|  | close (CONFIG); | 
|  |  | 
|  | ($logfile) = get_tag_values ("logfile", $config); | 
|  | ($timeout) = get_tag_values ("singletesttimeout", $config); | 
|  | ($display_errors) = get_tag_values("displayerrors", $config); | 
|  | ($display_warnings) = get_tag_values ("displaywarnings", $config); | 
|  | ($numthreads) = get_tag_values ("numthreads", $config); | 
|  | ($env_set_threads_command) = get_tag_values("envsetthreadscommand",$config); | 
|  | $env_set_threads_command =~ s/\%n/$numthreads/g; | 
|  | @languages = get_tag_values ("language", $config); | 
|  |  | 
|  | if (!defined($opt_compile)) {$opt_compile = 1;} | 
|  | if (!defined($opt_run))     {$opt_run = 1;} | 
|  | if (!defined($opt_orphan)) {$opt_orphan = 1;} | 
|  | if (!defined($opt_resultsfile)) {($opt_resultsfile) = get_tag_values("resultsfile", $config);} | 
|  | if ( defined($opt_numthreads) && ($opt_numthreads > 0)) {$numthreads = $opt_numthreads;} | 
|  | if ($debug_mode) { | 
|  | print <<EOF; | 
|  | Testsuite configuration: | 
|  | Logfile = $logfile | 
|  | Timeout = $timeout seconds | 
|  | Language:  $opt_lang | 
|  | Display errors:   $display_errors | 
|  | Display warnings: $display_warnings | 
|  | Resultsfile:      $opt_resultsfile | 
|  | Numthreads: $numthreads | 
|  | ------------------------------ | 
|  | EOF | 
|  | } | 
|  |  | 
|  | $num_construcs    = 0; | 
|  | $num_tests        = 0; | 
|  | $num_failed_tests = 0; | 
|  | $num_successful_tests   = 0; | 
|  | $num_verified_tests     = 0; | 
|  | $num_failed_compilation = 0; | 
|  |  | 
|  | $num_normal_tests_failed = 0; | 
|  | $num_normal_tests_compile_error = 0; | 
|  | $num_normal_tests_timed_out = 0; | 
|  | $num_normal_tests_successful = 0; | 
|  | $num_normal_tests_verified = 0; | 
|  |  | 
|  | $num_orphaned_tests_failed = 0; | 
|  | $num_orphaned_tests_compile_error = 0; | 
|  | $num_orphaned_tests_timed_out = 0; | 
|  | $num_orphaned_tests_successful = 0; | 
|  | $num_orphaned_tests_verified = 0; | 
|  |  | 
|  | if ($opt_help)         { print_help_text ();   exit 0; } | 
|  | if ($opt_listlanguages){ print_avail_langs (); exit 0; } | 
|  | if ($opt_list)     { print_avail_tests ();   exit 0; } | 
|  | if ($opt_testinfo) { print_testinfo ();      exit 0; } | 
|  | if ($opt_test)     { write_result_file_head(); | 
|  | execute_single_test (); exit 0; } | 
|  | if (-e $ARGV[0])   { write_result_file_head(); | 
|  | execute_testlist($ARGV[0]); print_results(); | 
|  | result_summary(); exit 0;} | 
|  |  | 
|  | ################################################################################ | 
|  | # sub function definitions | 
|  | ################################################################################ | 
|  |  | 
|  | # Function which prints the results file | 
|  | sub print_results | 
|  | { | 
|  | system("echo; cat $opt_resultsfile; echo;"); | 
|  | } | 
|  |  | 
|  | # Function which prints a summary of all test | 
|  | sub result_summary | 
|  | { | 
|  | my $num_directives = @test_results; | 
|  |  | 
|  | print <<EOF; | 
|  |  | 
|  | Summary: | 
|  | S Number of tested Open MP constructs: $num_constructs | 
|  | S Number of used tests:                $num_tests | 
|  | S Number of failed tests:              $num_failed_tests | 
|  | S Number of successful tests:          $num_successful_tests | 
|  | S + from this were verified:           $num_verified_tests | 
|  |  | 
|  | Normal tests: | 
|  | N Number of failed tests:              $num_normal_tests_failed | 
|  | N + from this fail compilation:        $num_normal_tests_compile_error | 
|  | N + from this timed out                $num_normal_tests_timed_out | 
|  | N Number of successful tests:          $num_normal_tests_successful | 
|  | N + from this were verified:           $num_normal_tests_verified | 
|  |  | 
|  | Orphaned tests: | 
|  | O Number of failed tests:              $num_orphaned_tests_failed | 
|  | O + from this fail compilation:        $num_orphaned_tests_compile_error | 
|  | O + from this timed out                $num_orphaned_tests_timed_out | 
|  | O Number of successful tests:          $num_orphaned_tests_successful | 
|  | O + from this were verified:           $num_orphaned_tests_verified | 
|  | EOF | 
|  |  | 
|  | } | 
|  |  | 
|  | # Function that executest the tests specified in the given list | 
|  | sub execute_testlist | 
|  | { | 
|  | my ($filename) = @_; | 
|  | # opening testlist | 
|  | open(TESTS,$filename) or error ("Could not open  $filename\n", 1); | 
|  | TEST: while (<TESTS>) { | 
|  | if (/^\s*#/) {next TEST;} | 
|  | if (/^\s*$/) {next TEST;} | 
|  | $opt_test = $_; | 
|  | chomp ($opt_test); | 
|  | execute_single_test (); | 
|  | } | 
|  | # print Dumper(@test_results); | 
|  | } | 
|  |  | 
|  | # Function that executes a system command but takes care of the global timeout | 
|  | # If command did not finish inbetween returns '-' otherwise the exit status of | 
|  | # the system command | 
|  | sub timed_sys_command | 
|  | { | 
|  | my ($command) = @_; | 
|  | my $exit_status = '-'; | 
|  |  | 
|  | # set up the timeout for the command | 
|  | eval { | 
|  | local $SIG{ALRM} = sub {die "alarm\n"}; | 
|  | alarm $timeout; | 
|  | log_message_add ("Starting command \"$command\""); | 
|  | $exit_status = system ($command); | 
|  | alarm 0; | 
|  | }; | 
|  | # check if command finished during the maximum execution time | 
|  | if ($@ eq "alarm\n") { | 
|  | # test timed out | 
|  | #		my $pid = Unix::PID->new(); | 
|  | #		$pid->get_pidof($command, 1); | 
|  | #		$pid->kill(); | 
|  | if ($debug_mode) { | 
|  | log_message_add ("Command \"$command\" reached max execution time.\n"); | 
|  | } | 
|  | return "TO"; | 
|  | } | 
|  | # test finished | 
|  | return $exit_status; | 
|  | } | 
|  |  | 
|  | # Function that runs the tests given as a array containing the testnames | 
|  | # Returns an array containing the percent values of the passed tests and the | 
|  | # successful crosstests. | 
|  | sub run_test | 
|  | { | 
|  | my ($testname, $orphan) = @_; | 
|  | my $bin_name, $cbin_name; | 
|  | my $cmd, $exit_status, $failed; | 
|  | my $resulttest, $resultctest; | 
|  |  | 
|  | # path to test and crosstest either in normal or in orphaned version | 
|  | if ($orphan) { | 
|  | $bin_name  = "bin/$opt_lang/orph_test_$testname"; | 
|  | $cbin_name = "bin/$opt_lang/orph_ctest_$testname"; | 
|  | } else { | 
|  | $bin_name  = "bin/$opt_lang/test_$testname"; | 
|  | $cbin_name = "bin/$opt_lang/ctest_$testname"; | 
|  | } | 
|  | # Check if executables exist | 
|  | if (! -e $bin_name) { | 
|  | test_error ("Could not find executable \"$bin_name\"."); | 
|  | return ('test' => '-', 'crosstest' => '-'); | 
|  | } | 
|  | # run the test | 
|  | $cmd = "$env_set_threads_command ./$bin_name >$bin_name.out"; | 
|  | print "Running test with $numthreads threads ."; | 
|  | $exit_status = timed_sys_command ($cmd); | 
|  | ############################################################ | 
|  | # Check if test finished within max execution time | 
|  | if ($exit_status eq 'TO') { | 
|  | print ".... failed (timeout)\n"; | 
|  | return ('test' => 'TO', 'crosstest' => '-') | 
|  | } | 
|  | ############################################################ | 
|  | # check if all tests were successful | 
|  | $failed = $exit_status >> 8; | 
|  | if ($failed < 0 or $failed > 100) { $failed = 100; } | 
|  | $resulttest = 100 - $failed; | 
|  | if ($resulttest eq 100) { | 
|  | print ".... success ..."; | 
|  | } else { | 
|  | print ".... failed $failed\% of the tests\n"; | 
|  | return ('test' => $resulttest, 'crosstest' => '-'); | 
|  | } | 
|  | ############################################################ | 
|  |  | 
|  | # do crosstest | 
|  | # check if executable exist | 
|  | if (! -e $cbin_name) { | 
|  | test_error ("Could not find executable \"$cbin_name\"."); | 
|  | print "... not verified (crosstest missing)\n"; | 
|  | return ('test' => $resulttest, 'crosstest' => '-'); | 
|  | } | 
|  | # run crosstest | 
|  | # Test was successful, so it makes sense to run the crosstest | 
|  | $cmd = "$env_set_threads_command ./$cbin_name > $cbin_name.out"; | 
|  | $exit_status = timed_sys_command ($cmd); | 
|  | ############################################################ | 
|  | # Check if crosstest finished within max execution time | 
|  | if ($exit_status eq 'TO') { | 
|  | print "... not verified (timeout)\n"; | 
|  | return ('test' => $result, 'crosstest' => 'TO'); | 
|  | } | 
|  | ############################################################ | 
|  | # test if crosstests failed as expected | 
|  | $resultctest = $exit_status >> 8; | 
|  | if ($resultctest > 0) { | 
|  | print "... and verified with $resultctest\% certainty\n"; | 
|  | } else { | 
|  | print "... but might be lucky\n"; | 
|  | } | 
|  | return ('test' => $resulttest, 'crosstest' => $resultctest); | 
|  | ############################################################ | 
|  | } | 
|  |  | 
|  | # Function that generates the test binaries out of the sourcecode | 
|  | sub compile_src | 
|  | { | 
|  | my ($testname, $orphan) = @_; | 
|  | print "Compiling soures ............"; | 
|  | if ($orphan) { | 
|  | # Make orphaned tests | 
|  | $exec_name     = "bin/$opt_lang/orph_test_$testname"; | 
|  | $crossexe_name = "bin/$opt_lang/orph_ctest_$testname"; | 
|  | $resulttest  = system ("make $exec_name > $exec_name\_compile.log" ); | 
|  | $resultctest = system ("make $crossexe_name > $crossexe_name\_compile.log" ); | 
|  | } else { | 
|  | # Make test | 
|  | $exec_name     = "bin/$opt_lang/test_$testname"; | 
|  | $crossexe_name = "bin/$opt_lang/ctest_$testname"; | 
|  | $resulttest  = system ("make $exec_name > $exec_name\_compile.log" ); | 
|  | $resultctest = system ("make $crossexe_name > $crossexe_name\_compile.log" ); | 
|  | } | 
|  | if ($resulttest) { test_error ("Compilation of the test failed."); } | 
|  | if ($resultctest){ test_error ("Compilation of the crosstest failed."); } | 
|  |  | 
|  | if ($resulttest or $resultctest) { | 
|  | print ".... failed\n"; | 
|  | return 0; | 
|  | } else { | 
|  | print ".... success\n"; | 
|  | return 1; | 
|  | } | 
|  | } | 
|  |  | 
|  | # Function which prepare the directory structure: | 
|  | sub init_directory_structure | 
|  | { | 
|  | my ($language) = @_; | 
|  | if (-e "bin" && -d "bin") { warning ("Old binary directory detected!");} | 
|  | else { system ("mkdir bin"); } | 
|  | if (-e "bin/$language" && -d "bin/$language") { | 
|  | warning ("Old binary directory for language $language found.");} | 
|  | else { system ("mkdir bin/$language"); } | 
|  | } | 
|  |  | 
|  | # Function that generates the sourcecode for the given test | 
|  | sub make_src | 
|  | { | 
|  | my ($testname, $orphan) = @_; | 
|  | my $template_file; | 
|  | my $src_name; | 
|  |  | 
|  | $template_file = "$dir/$testname.$extension"; | 
|  | if (!-e $template_file) { test_error ("Could not find template for \"$testname\""); } | 
|  |  | 
|  | print "Generating sources .........."; | 
|  | if ($orphan) { | 
|  | # Make orphaned tests | 
|  | $src_name = "bin/$opt_lang/orph_test_$testname.$extension"; | 
|  | $resulttest = system ("./$templateparsername --test --orphan $template_file $src_name"); | 
|  | $src_name = "bin/$opt_lang/orph_ctest_$testname.$extension"; | 
|  | $resultctest = system ("./$templateparsername --crosstest --orphan $template_file $src_name"); | 
|  | } else { | 
|  | # Make test | 
|  | $src_name = "bin/$opt_lang/test_$testname.$extension"; | 
|  | $resulttest = system ("./$templateparsername --test --noorphan $template_file $src_name"); | 
|  | $src_name = "bin/$opt_lang/ctest_$testname.$extension"; | 
|  | $resultctest = system ("./$templateparsername --crosstest --noorphan $template_file $src_name"); | 
|  | } | 
|  | if ($resulttest) { test_error ("Generation of sourcecode for the test failed."); } | 
|  | if ($resultctest){ test_error ("Generation of sourcecode for the crosstest failed."); } | 
|  |  | 
|  | if ($resulttest or $resultctest) { | 
|  | print ".... failed\n"; | 
|  | return 0; | 
|  | } else { | 
|  | print ".... success\n"; | 
|  | return 1; | 
|  | } | 
|  | } | 
|  |  | 
|  | # Function which checks if a given test is orphanable | 
|  | sub test_is_orphanable | 
|  | { | 
|  | my ($testname) = @_; | 
|  | my $src; | 
|  | my $file = "$dir/$testname.$extension"; | 
|  | if(! -e $file){ test_error ("Could not find test file $file\n");} | 
|  | open (TEST, "<$file") or test_error ("Could not open test file $file\n"); | 
|  | while (<TEST>) { $src .= $_; } | 
|  | close (TEST); | 
|  | return $src =~/ompts:orphan/; | 
|  | } | 
|  |  | 
|  | sub write_result_file_head | 
|  | { | 
|  | open (RESULTS, ">$opt_resultsfile") or error ("Could not open file '$opt_resultsfile' to write results.", 1); | 
|  | $resultline = sprintf "%-25s %-s\n", "#Tested Directive", "\tt\tct\tot\toct"; | 
|  | print RESULTS $resultline; | 
|  | } | 
|  |  | 
|  | # Function which adds a result to the list of results | 
|  | sub add_result | 
|  | { | 
|  | my ($testname, $result) = @_; | 
|  | #	print Dumper(@{$result}); | 
|  |  | 
|  | $num_constructs++; | 
|  |  | 
|  | open (RESULTS, ">>$opt_resultsfile") or error ("Could not open file '$opt_resultsfile' to write results.", 1); | 
|  |  | 
|  | if (${$result}[0][0]) { | 
|  | $num_tests ++;} | 
|  |  | 
|  | if ($opt_compile and ${$result}[0][1] eq 0) { | 
|  | ${$result}[0][2]{test}      = 'ce'; | 
|  | ${$result}[0][2]{crosstest} = '-'; | 
|  | $num_normal_tests_compile_error++; | 
|  | $num_normal_tests_failed++; | 
|  | } | 
|  |  | 
|  | if ($opt_run and ${$result}[0][2] and ${$result}[0][2]{test} ne 'ce') { | 
|  | if (${$result}[0][2]{test} == 100) { | 
|  | $num_normal_tests_successful++; | 
|  | if (${$result}[0][2]{crosstest} == 100){ | 
|  | $num_normal_tests_verified++;} | 
|  | } elsif (${$result}[0][2]{test} eq 'TO'){ | 
|  | $num_normal_tests_timed_out++; | 
|  | $num_normal_tests_failed++; | 
|  | } else { | 
|  | $num_normal_tests_failed++; | 
|  | } | 
|  | } | 
|  | $resultline = "${$result}[0][2]{test}\t${$result}[0][2]{crosstest}\t"; | 
|  |  | 
|  | if (${$result}[1][0]) { | 
|  | $num_tests ++;} | 
|  | else { $resultline .= "-\t-\n"; } | 
|  |  | 
|  | if ($opt_compile and ${$result}[1][1] eq 0) { | 
|  | ${$result}[1][2]{test}      = 'ce'; | 
|  | ${$result}[1][2]{crosstest} = '-'; | 
|  | $num_orphaned_tests_compile_error++; | 
|  | $num_orphaned_tests_failed++; | 
|  | } | 
|  |  | 
|  | if ($opt_run and ${$result}[1][2] and ${$result}[1][2]{test} ne 'ce') { | 
|  | if (${$result}[1][2]{test} == 100) { | 
|  | $num_orphaned_tests_successful++; | 
|  | if (${$result}[1][2]{crosstest} == 100){ | 
|  | $num_orphaned_tests_verified++;} | 
|  | } elsif (${$result}[1][2]{test} eq 'TO'){ | 
|  | $num_orphaned_tests_timed_out++; | 
|  | $num_orphaned_tests_failed++; | 
|  | } else { | 
|  | $num_orphaned_tests_failed++; | 
|  | } | 
|  | } | 
|  | $resultline .= "${$result}[1][2]{test}\t${$result}[1][2]{crosstest}\n"; | 
|  |  | 
|  | $num_failed_tests = $num_normal_tests_failed + $num_orphaned_tests_failed; | 
|  | $num_failed_compilation = $num_normal_tests_compile_error + $num_orphaned_tests_compile_error; | 
|  | $num_successful_tests = $num_normal_tests_successful + $num_orphaned_tests_successful; | 
|  | $num_verified_tests = $num_normal_tests_verified + $num_orphaned_tests_verified; | 
|  |  | 
|  | $resultline2 = sprintf "%-25s %-s", "$testname", "\t$resultline"; | 
|  | print RESULTS $resultline2; | 
|  | } | 
|  |  | 
|  | # Function which executes a single test | 
|  | sub execute_single_test | 
|  | { | 
|  | my @result; | 
|  | init_language_settings ($opt_lang); | 
|  | init_directory_structure ($opt_lang); | 
|  | log_message_add ("Testing for \"$opt_test\":"); | 
|  | print "Testing for \"$opt_test\":\n"; | 
|  | # tests in normal mode | 
|  | if ($opt_compile){ $result[0][0] = make_src ($opt_test, 0); | 
|  | $result[0][1] = compile_src ($opt_test, 0);} | 
|  | if ($opt_run && $result[0][1] == 1) { | 
|  | $result[0][2] = {run_test ($opt_test, 0)};} | 
|  | # tests in orphaned mode | 
|  | if ($opt_orphan && test_is_orphanable($opt_test)){ | 
|  | log_message_add ("Testing for \"$opt_test\" in orphaned mode:"); | 
|  | print "+ orphaned mode:\n"; | 
|  | if ($opt_compile) { $result[1][0] = make_src ($opt_test, 1); | 
|  | $result[1][1] = compile_src ($opt_test, 1);} | 
|  | if ($opt_run && $result[1][1] == 1) { | 
|  | $result[1][2] = {run_test ($opt_test, 1)};} | 
|  | } | 
|  | add_result($opt_test, \@result); | 
|  | } | 
|  |  | 
|  | # Function that prints info about a given test | 
|  | sub print_testinfo | 
|  | { | 
|  | init_language_settings($opt_lang); | 
|  | my $doc = ""; | 
|  | my $file = $dir."/".$opt_testinfo.".".$extension; | 
|  | if (! -e $file) {error ("Could not find template for test $opt_testinfo", 5);} | 
|  | open (TEST,"<$file") or error ("Could not open template file \"$file\" for test $opt_testinfo", 6); | 
|  | while (<TEST>) {$doc .= $_;} | 
|  | close (TEST); | 
|  |  | 
|  | (my $omp_version) = get_tag_values ("ompts:ompversion", $doc); | 
|  | (my $dependences) = get_tag_values ("ompts:dependences", $doc); | 
|  | (my $description) = get_tag_values ("ompts:testdescription", $doc); | 
|  | my $orphanable = 'no'; | 
|  | if ($doc =~ /ompts:orphan/) {$orphanable = 'yes';} | 
|  | print <<EOF; | 
|  | Info for test $opt_testinfo: | 
|  | Open MP standard: $omp_version | 
|  | Orphaned mode: $orphanable | 
|  | Dependencies:  $dependences | 
|  | Description:   $description | 
|  | EOF | 
|  | } | 
|  |  | 
|  | # Function that initializes the settings for the given language | 
|  | sub init_language_settings | 
|  | { | 
|  | my ($language) = @_; | 
|  | foreach my $lang (@languages) { | 
|  | (my $name) = get_tag_values ("languagename", $lang); | 
|  | if ($name eq $language) { | 
|  | ($extension) = get_tag_values ("fileextension", $lang); | 
|  | ($dir)       = get_tag_values ("dir", $lang); | 
|  | ($templateparsername) = get_tag_values ("templateparsername", $lang); | 
|  | last; | 
|  | } | 
|  | } | 
|  | # Check if we found the specified language in the config file | 
|  | if (!$extension and !$dir) { | 
|  | error ("Language $language could not be found.\n", 3); | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  | # Function that prints all available tests for the given language | 
|  | sub print_avail_tests | 
|  | { | 
|  | init_language_settings($opt_lang); | 
|  | my @tests; | 
|  | opendir(DIR,"$dir") or error ("Could not open directory $dir", 4); | 
|  | while($_ = readdir(DIR)) { if (/\.$extension$/) {s/\.$extension//; push (@tests, $_);}} | 
|  | closedir(DIR); | 
|  | print "Found ".(@tests)." tests:\n". "-" x 30 . "\n"; | 
|  | foreach (@tests) { print $_."\n";} | 
|  | } | 
|  |  | 
|  | # Function that prints all available tests for the given language | 
|  | sub print_avail_langs | 
|  | { | 
|  | if (@languages > 0) { | 
|  | print "Available languages:\n"; | 
|  | foreach (@languages) { | 
|  | (my $name) = get_tag_values ("languagename", $_); | 
|  | print "$name\n"; | 
|  | } | 
|  | } else { | 
|  | print "No languages available\n"; | 
|  | } | 
|  | } | 
|  |  | 
|  | # Function that prints the error message | 
|  | sub print_help_text | 
|  | { | 
|  | print <<EOF; | 
|  | runtest.pl [options] [FILE] | 
|  |  | 
|  | Executes the tests listed in FILE. FILE has to contain the names of the tests, | 
|  | one test per line. Lines starting with '#' will be ignored. | 
|  | A language has to be specified for all commands except --help and --listlanguages. | 
|  |  | 
|  | Options: | 
|  | --help            displays this help message | 
|  | --listlanguages   lists all available languages | 
|  | --lang=s          select language | 
|  | --list            list available tests for a language | 
|  | --testinfo=NAME   show info for test NAME | 
|  | --numthreads=NUM  set number of threads (overwrites config file settings) | 
|  | --test=NAME       execute single test NAME | 
|  | --nocompile       do not compile tests | 
|  | --norun           do not run tests | 
|  | --noorphan        switch of orphaned tests | 
|  | --resultfile=NAME use NAME as resultfile (overwrites config file settings) | 
|  | EOF | 
|  | } | 
|  |  | 
|  | # Function that writes an error message for a failed test / part of a test | 
|  | sub test_error | 
|  | { | 
|  | my ($message) = @_; | 
|  | log_message_add ("ERROR: $message"); | 
|  | if ($display_errors eq 1) { print STDERR "ERROR: $message\n"; } | 
|  | } | 
|  |  | 
|  | # Function that returns an warning message | 
|  | sub warning { | 
|  | my ($message) = @_; | 
|  | if ($display_warnings eq 1) { print "Warniong: $message\n"; } | 
|  | log_message_add ("Warning: $message"); | 
|  | } | 
|  |  | 
|  | # Function that returns an error message and exits with the specified error code | 
|  | sub error { | 
|  | my ($message, $error_code) = @_; | 
|  | if ($display_errors eq 1) { print STDERR "ERROR: $message\n"; } | 
|  | log_message_add ("ERROR: $message"); | 
|  | exit ($error_code); | 
|  | } | 
|  |  | 
|  | # Function which adds an new entry into the logfile together with a timestamp | 
|  | sub log_message_add | 
|  | { | 
|  | (my $message) = @_; | 
|  | ($sec,$min,$hour,$mday,$mon,$year,$wday,$ydat,$isdst) = localtime(); | 
|  | if(length($hour) == 1) { $hour="0$hour"; } | 
|  | if(length($min) == 1)  { $min="0$min";   } | 
|  | if(length($sec) == 1)  { $sec="0$sec";   } | 
|  | $mon=$mon+1; | 
|  | $year=$year+1900; | 
|  | open (LOGFILE,">>$logfile") or die "ERROR: Could not create $logfile\n"; | 
|  | print LOGFILE "$mday/$mon/$year $hour.$min.$sec: $message\n"; | 
|  | } |