This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
new perldelta
[perl5.git] / t / TEST
diff --git a/t/TEST b/t/TEST
index fd07c6b..60c3f01 100755 (executable)
--- a/t/TEST
+++ b/t/TEST
@@ -1,4 +1,4 @@
-#!./perl -w
+#!./perl
 
 # This is written in a peculiar style, since we're trying to avoid
 # most of the constructs we'll be testing for.  (This comment is
 # In which case, we need to stop t/TEST actually running tests, as all
 # t/harness needs are its subroutines.
 
+# Measure the elapsed wallclock time.
+my $t0 = time();
+
 # If we're doing deparse tests, ignore failures for these
 my $deparse_failures;
 
 # And skip even running these
 my $deparse_skips;
 
+my $deparse_skip_file = '../Porting/deparse-skips.txt';
+
 # directories with special sets of test switches
 my %dir_to_switch =
     (base => '',
@@ -36,9 +41,7 @@ my %abs = (
           '../cpan/Archive-Tar' => 1,
           '../cpan/AutoLoader' => 1,
           '../cpan/CPAN' => 1,
-          '../cpan/Devel-PPPort' => 1,
           '../cpan/Encode' => 1,
-          '../cpan/ExtUtils-Command' => 1,
           '../cpan/ExtUtils-Constant' => 1,
           '../cpan/ExtUtils-Install' => 1,
           '../cpan/ExtUtils-MakeMaker' => 1,
@@ -46,20 +49,18 @@ my %abs = (
           '../cpan/File-Fetch' => 1,
           '../cpan/IPC-Cmd' => 1,
           '../cpan/IPC-SysV' => 1,
-          '../cpan/Locale-Codes' => 1,
           '../cpan/Module-Load' => 1,
           '../cpan/Module-Load-Conditional' => 1,
-          '../cpan/Parse-CPAN-Meta' => 1,
           '../cpan/Pod-Simple' => 1,
           '../cpan/Test-Simple' => 1,
           '../cpan/podlators' => 1,
           '../dist/Cwd' => 1,
+          '../dist/Devel-PPPort' => 1,
           '../dist/ExtUtils-ParseXS' => 1,
           '../dist/Tie-File' => 1,
          );
 
-my %temp_no_core =
-    ('../cpan/B-Debug' => 1,
+my %temp_no_core = (
      '../cpan/Compress-Raw-Bzip2' => 1,
      '../cpan/Compress-Raw-Zlib' => 1,
      '../cpan/Devel-PPPort' => 1,
@@ -67,20 +68,19 @@ my %temp_no_core =
      '../cpan/IO-Compress' => 1,
      '../cpan/MIME-Base64' => 1,
      '../cpan/parent' => 1,
-     '../cpan/Parse-CPAN-Meta' => 1,
      '../cpan/Pod-Simple' => 1,
      '../cpan/podlators' => 1,
      '../cpan/Test-Simple' => 1,
      '../cpan/Tie-RefHash' => 1,
      '../cpan/Unicode-Collate' => 1,
-     '../cpan/Unicode-Normalize' => 1,
+     '../dist/Unicode-Normalize' => 1,
     );
 
 # delete env vars that may influence the results
 # but allow override via *_TEST env var if wanted
 # (e.g. PERL5OPT_TEST=-d:NYTProf)
 my @bad_env_vars = qw(
-    PERL5LIB PERLLIB PERL5OPT
+    PERL5LIB PERLLIB PERL5OPT PERL_UNICODE
     PERL_YAML_BACKEND PERL_JSON_BACKEND
 );
 
@@ -107,79 +107,87 @@ my %skip = (
            '.svn' => 1,
           );
 
+
+if ($::do_nothing) {
+    return 1;
+}
+
 $| = 1;
 
 # for testing TEST only
 #BEGIN { require '../lib/strict.pm'; "strict"->import() };
 #BEGIN { require '../lib/warnings.pm'; "warnings"->import() };
 
-# allow setting -options from env
-unshift @ARGV, split /;/, $ENV{TEST_OPTS} if $ENV{TEST_OPTS};
+my $OS = $ENV{FAKE_OS} || $^O;
+
+my $is_vms   = $OS eq "VMS";
+my $is_win32 = $OS eq "MSWin32";
+my $is_os2   = $OS eq "os2";
 
 # remove empty elements due to insertion of empty symbols via "''p1'" syntax
-@ARGV = grep($_,@ARGV) if $^O eq 'VMS';
-our $show_elapsed_time = $ENV{HARNESS_TIMER} || 0;
+@ARGV = grep($_,@ARGV) if $is_vms;
 
-{   # create timestamp for any reports written, so theyre corelatable
-    my @dt = localtime;
-    $dt[5] += 1900; $dt[4] += 1; # fix year, month
-    $::tstamp = sprintf("%d-%.2d%.2d-%.2d%.2d-%.2d-$$", @dt[5,4,3,2,1,0]);
-}
+our $show_elapsed_time = $ENV{HARNESS_TIMER} || 0;
 
-# wrapper template for linux perf
-our %cmdwrap = (
-    tool       => "perf",      # path
-    cmd                => "stat",      # others possible, none tried
-    rptdir     => $ENV{PWD},   # typically ./t, better if absolute
-    name       => "",          # $::tstamp prefixed implicitly
-    # reps     => 1            # 
-    opts       => "",          # pass-thru to perf stat: 'opts=-x,' gives CSV
-    );
+my $dump_tests = 0;
 
 # Cheesy version of Getopt::Std.  We can't replace it with that, because we
 # can't rely on require working.
 {
+    my %opt_vars = (
+       benchmark => \$::benchmark,
+       core      => \$::core,
+       v         => \$::verbose,
+       torture   => \$::torture,
+       utf8      => \$::with_utf8,
+       utf16     => \$::with_utf16,
+       taintwarn => \$::taintwarn,
+       dumptests => \$dump_tests,
+    );
+
     my @argv = ();
     foreach my $idx (0..$#ARGV) {
-       push( @argv, $ARGV[$idx] ), next unless $ARGV[$idx] =~ /^-(\S+?)(?:=(.+))?$/;
-       $::benchmark = 1 if $1 eq 'benchmark';
-       $::core    = 1 if $1 eq 'core';
-       $::verbose = 1 if $1 eq 'v';
-       $::torture = 1 if $1 eq 'torture';
-       $::with_utf8 = 1 if $1 eq 'utf8';
-       $::with_utf16 = 1 if $1 eq 'utf16';
-       $::taintwarn = 1 if $1 eq 'taintwarn';
-       if ($1 =~ /^deparse(,.+)?$/) {
+       my $opt;
+       if ($ARGV[$idx] =~ /^-?-(\S+)$/) {
+           $opt = $1;
+       } else {
+           push @argv, $ARGV[$idx];
+           next;
+       }
+       if (my $ref = $opt_vars{$opt}) {
+           $$ref = 1;
+       }
+       elsif ($opt =~ /^deparse(,.+)?$/) {
            $::deparse = 1;
            $::deparse_opts = $1;
             _process_deparse_config();
        }
-       if ($1 eq 'lxperf') {
-           die "perf only available on linux" unless $^O eq 'linux';
-           $::perf = 1;
-           next unless $2;
-           # $2 is either Reps or : delimited $k=$v pairs
-           my (@v) = split /:/, $2;
-           $cmdwrap{reps} = $v[0] if @v == 1 and $v[0] =~ /^\d+$/;
-           # parse as $k=$v to override %cmdwrap defaults
-           m/(.+?)=(.+)/ and $cmdwrap{$1} = $2 for @v;
+       else {
+           die "Unknown option '$opt'\n";
        }
     }
     @ARGV = @argv;
 }
 
-if ($::do_nothing || $::do_nothing) { # set by harness b4 requiring us
-    return 1;
-}
-
 chdir 't' if -f 't/TEST';
 if (-f 'TEST' && -f 'harness' && -d '../lib') {
     @INC = '../lib';
 }
 
-die "You need to run \"make test\" first to set things up.\n"
+die "You need to run \"make test_prep\" first to set things up.\n"
   unless -e 'perl' or -e 'perl.exe' or -e 'perl.pm';
 
+if ($is_win32) {
+    # String eval to avoid loading File::Glob on non-miniperl.
+    # (Windows only uses this script for miniperl.)
+    my @argv;
+    if (eval '@argv = map glob, @ARGV; 1') {
+       @ARGV = @argv;
+    } else {
+       die "Failed to glob \@ARGV: $@";
+    }
+}
+
 # check leakage for embedders
 $ENV{PERL_DESTRUCT_LEVEL} = 2 unless exists $ENV{PERL_DESTRUCT_LEVEL};
 # check existence of all symbols
@@ -192,16 +200,15 @@ my %timings = (); # testname => [@et] pairs if $show_elapsed_time.
 
 # Roll your own File::Find!
 our @found;
-sub _find_tests { @found = (); push @ARGV, _find_files('\.t$', $_[0]) }
+sub _find_tests { @found=(); push @ARGV, _find_files('\.t$', $_[0]) }
 sub _find_files {
     my($patt, @dirs) = @_;
     for my $dir (@dirs) {
        opendir DIR, $dir or die "Trouble opening $dir: $!";
        foreach my $f (sort { $a cmp $b } readdir DIR) {
            next if $skip{$f};
-
+           $dir =~ s/(?<!\^)\.dir(;1)?$//i if $is_vms; # trim .DIR extension
            my $fullpath = "$dir/$f";
-           
            if (-d $fullpath) {
                _find_files($patt, $fullpath);
            } elsif ($f =~ /$patt/) {
@@ -246,7 +253,7 @@ sub _scan_test {
 
     close $script;
 
-    my $perl = './perl';
+    my $perl = $is_win32 ? '.\perl' : './perl';
     my $lib  = '../lib';
     my $run_dir;
     my $return_dir;
@@ -312,13 +319,14 @@ sub _cmd {
     }
     elsif ($type eq 'perl') {
         my $perl = $options->{perl};
-        my $redir = $^O eq 'VMS' ? '2>&1' : '';
+        my $redir = $is_vms ? '2>&1' : '';
 
         if ($ENV{PERL_VALGRIND}) {
             my $perl_supp = $options->{return_dir} ? "$options->{return_dir}/perl.supp" : "perl.supp";
             my $valgrind_exe = $ENV{VALGRIND} // 'valgrind';
             if ($options->{run_dir}) {
-                $Valgrind_Log = "$options->{run_dir}/$Valgrind_Log";
+                require Cwd;
+                $Valgrind_Log = Cwd::abs_path("$options->{run_dir}/$Valgrind_Log");
             }
             my $vg_opts = $ENV{VG_OPTS}
               //   "--log-file=$Valgrind_Log "
@@ -331,14 +339,6 @@ sub _cmd {
            }
             $perl = "$valgrind_exe $vg_opts $perl";
         }
-       if ($::perf) {
-           my $ofile = "$cmdwrap{rptdir}/$::tstamp$cmdwrap{name}.perf";
-           my $wrapper = "$cmdwrap{tool} $cmdwrap{cmd} "
-               . ( defined $cmdwrap{reps} && $cmdwrap{reps} > 0
-                   ? "--repeat $cmdwrap{reps}" : "" )
-               . " --append -o $ofile $cmdwrap{opts} -- ";
-           $perl = "$wrapper $perl";
-       }
 
         my $args = "$options->{testswitch} $options->{switch} $options->{utf8}";
         $cmd = $perl . _quote_args($args) . " $test $redir";
@@ -410,7 +410,7 @@ sub _quote_args {
     foreach (split(/\s+/,$args)) {
        # In VMS protect with doublequotes because otherwise
        # DCL will lowercase -- unless already doublequoted.
-       $_ = q(").$_.q(") if ($^O eq 'VMS') && !/^\"/ && length($_) > 0;
+       $_ = q(").$_.q(") if $is_vms && !/^\"/ && length($_) > 0;
        $argstring = $argstring . ' ' . $_;
     }
     return $argstring;
@@ -422,22 +422,63 @@ sub _populate_hash {
 }
 
 sub _tests_from_manifest {
-    my ($extensions, $known_extensions) = @_;
+    my ($extensions, $known_extensions, $all) = @_;
+    s/\bCwd\b/PathTools/, s!\bList/Util\b!Scalar/List/Utils!
+       for $extensions, $known_extensions;
     my %skip;
     my %extensions = _populate_hash($extensions);
     my %known_extensions = _populate_hash($known_extensions);
+    my %printed_skip_warning;
 
     foreach (keys %known_extensions) {
        $skip{$_} = 1 unless $extensions{$_};
     }
 
     my @results;
+    my %non_ext;
+    push @results, \%non_ext if $all;
     my $mani = '../MANIFEST';
     if (open(MANI, $mani)) {
        while (<MANI>) {
-           if (m!^((?:cpan|dist|ext)/(\S+)/+(?:[^/\s]+\.t|test\.pl)|lib/\S+?(?:\.t|test\.pl))\s!) {
+           chomp;
+           my ($file)= split /\t/, $_;
+           if ($file =~ m!^((?:cpan|dist|ext)/(\S+)/+(?:[^/\s]+\.t|test\.pl)|lib/\S+?(?:\.t|test\.pl))\z!) {
                my $t = $1;
                my $extension = $2;
+
+               if (    ord "A" != 65
+                    && defined $extension
+                    && $extension =~ m! \b (?:
+                                               Archive-Tar/
+                                             | Config-Perl-V/
+                                             | CPAN-Meta/
+                                             | CPAN-Meta-YAML/
+                                             | Digest-SHA/
+                                             | ExtUtils-MakeMaker/
+                                             | HTTP-Tiny/
+                                             | IO-Compress/
+                                             | JSON-PP/
+                                             | libnet/
+                                             | MIME-Base64/
+                                             | podlators/
+                                             | Pod-Simple/
+                                             | Pod-Checker/
+                                             | Digest-MD5/
+                                             | Test-Harness/
+                                             | IPC-Cmd/
+                                             | Encode/
+                                             | Socket/
+                                             | ExtUtils-Manifest/
+                                             | Module-Metadata/
+                                             | PerlIO-via-QuotedPrint/
+                                           )
+                                      !x)
+               {
+                   print STDERR "Skipping testing of $extension on EBCDIC\n"
+                                    unless $printed_skip_warning{$extension}++;
+                   next;
+               }
+
                if (!$::core || $t =~ m!^lib/[a-z]!) {
                    if (defined $extension) {
                        $extension =~ s!/t(:?/\S+)*$!!;
@@ -452,6 +493,17 @@ sub _tests_from_manifest {
                    $::path_to_name{$path} = $t;
                }
            }
+           elsif ($file=~m!/(?:test\.pl|[^/\s]+\.t)\z! and $file ne "t/test.pl") {
+               my $munged = $file;
+               next if $munged=~m!^(?:t/)?os2/!        and !$is_os2;
+               next if $munged=~m!^(?:t/)?win32/!      and !$is_win32;
+               next if $munged=~m!^(?:t/)?japh/!       and !($::torture or $ENV{PERL_TORTURE_TEST});
+               next if $munged=~m!^(?:t/)?benchmark/!  and !($::benchmark or $ENV{PERL_BENCHMARK});
+               next if $munged=~m!^(?:t/)?bigmem/!     and !$ENV{PERL_TEST_MEMORY};
+               $munged =~ s!t/!! or $munged = "../$munged";
+
+               $non_ext{$munged}++;
+           }
        }
        close MANI;
     } else {
@@ -460,21 +512,65 @@ sub _tests_from_manifest {
     return @results;
 }
 
+sub dump_tests {
+    my ($ary) = @_;
+    for my $test (sort @$ary) {
+        # convert it to a path from the root of the repo
+        $test=~s!^\.\./!! or $test=~s!^!t/!;
+        print "$test\n";
+    }
+    exit(0);
+}
+
+sub filter_taint_tests {
+    my $tests = shift;
+    require Config;
+    return unless $Config::Config{taint_disabled} eq "define";
+
+    # These are test files which are known to fail with -DNO_TAINT_SUPPORT
+    # but which do not have "taint" in their name, nor have shebang lines
+    # with -t or -T in them. So we exclude them specifically instead.
+    my %known_tainter = map { $_ => 0 } (
+        '../cpan/Test-Harness/t/regression.t',
+        '../cpan/Test-Harness/t/source_handler.t',
+        '../cpan/Test-Harness/t/compat/inc-propagation.t',
+    );
+    @$tests = grep {
+        my $file = $_;
+        open my $ifh, "<", $file
+            or die "Failed to read: '$file': $!";
+        my $line = <$ifh>;
+        my $keep = $file=~/taint/ ? 0 : ($known_tainter{$file} // 1);
+        if ($line=~/^#!.*perl\s+-(\w+)/) {
+            my $switch = $1;
+            if ($switch =~ s/[Tt]//) {
+                $keep = 0;
+            }
+        }
+        $keep
+    } @$tests;
+}
+
+
 unless (@ARGV) {
     # base first, as TEST bails out if that can't run
     # then comp, to validate that require works
     # then run, to validate that -M works
     # then we know we can -MTestInit for everything else, making life simpler
-    foreach my $dir (qw(base comp run cmd io re opbasic op uni mro perf)) {
+
+    # NOTE that _find_tests() is recursive, unlike what test_harness uses.
+    foreach my $dir (qw(base comp run cmd io re opbasic op uni mro class perf test_pl)) {
        _find_tests($dir);
     }
     unless ($::core) {
        _find_tests('porting');
-       _find_tests("lib"); 
+        _find_tests("lib");
     }
+    _find_tests('win32') if $is_win32;
+    _find_tests('os2')  if $is_os2;
     # Config.pm may be broken for make minitest. And this is only a refinement
     # for skipping tests on non-default builds, so it is allowed to fail.
-    # What we want to to is make a list of extensions which we did not build.
+    # What we want to do is make a list of extensions which we did not build.
     my $configsh = '../config.sh';
     my ($extensions, $known_extensions);
     if (-f $configsh) {
@@ -500,11 +596,49 @@ unless (@ARGV) {
     # something is that badly wrong.
     push @ARGV, _tests_from_manifest($extensions, $known_extensions);
     unless ($::core) {
-       _find_tests('japh') if $::torture;
+       _find_tests('japh') if $::torture or $ENV{PERL_TORTURE_TEST};
        _find_tests('benchmark') if $::benchmark or $ENV{PERL_BENCHMARK};
        _find_tests('bigmem') if $ENV{PERL_TEST_MEMORY};
     }
 }
+@ARGV= do {
+    my @order= (
+       "test_pl",
+       "base",
+       "comp",
+       "run",
+       "cmd",
+       "io",
+       "re",
+       "opbasic",
+       "op",
+       "op/hook",
+       "uni",
+       "mro",
+       "class",
+       "lib",
+       "ext",
+       "dist",
+       "cpan",
+       "perf",
+       "porting",
+    );
+    my %order= map { $order[$_] => 1+$_ } 0..$#order;
+    my $idx= 0;
+    map {
+       $_->[0]
+    } sort {
+           $a->[3] <=> $b->[3] ||
+           $a->[1] <=> $b->[1]
+    } map {
+       my $root= /(\w+)/ ? $1 : "";
+       [ $_, $idx++, $root, $order{$root}||=0 ]
+    } @ARGV;
+};
+
+dump_tests(\@ARGV) if $dump_tests;
+
+filter_taint_tests(\@ARGV);
 
 if ($::deparse) {
     _testprogs('deparse', '',   @ARGV);
@@ -567,9 +701,10 @@ EOT
     my $grind_ct = 0;          # count of non-empty valgrind reports
     my $total_files = @tests;
     my $good_files = 0;
-    my $tested_files = 0;
+    my $tested_files  = 0;
     my $totmax = 0;
     my %failed_tests;
+    my @unexpected_pass; # files where deparse-skips.txt says fail but passed
     my $toolnm;                # valgrind, cachegrind, perf
 
     while (my $test = shift @tests) {
@@ -594,7 +729,7 @@ EOT
        my $te = $::path_to_name{$test} . '.'
                    x ($dotdotdot - length($::path_to_name{$test})) .' ';
 
-       if ($^O ne 'VMS') {  # defer printing on VMS due to piping bug
+       if (!$is_vms) {  # defer printing on VMS due to piping bug
            print $te;
            $te = '';
        }
@@ -603,16 +738,16 @@ EOT
 
        my $results = _run_test($test, $type);
 
-       my $failure = "";
-       my $next = 0;                   # ++ after each ok M
-       my $seen_leader = 0;            # set after "1..N"
-       my $seen_ok = 0;                # set after "ok M"
-       my $trailing_leader = 0;        # set after "1..N" if $seen_ok
-       my $max;                        # set to N after "1..N"
+       my $failure;
+       my $next = 0;
+       my $seen_leader = 0;
+       my $seen_ok = 0;
+       my $trailing_leader = 0;
+       my $max;
        my %todo;
        while (<$results>) {
            next if /^\s*$/; # skip blank lines
-           if (/^1..$/ && ($^O eq 'VMS')) {
+           if (/^1..$/ && $is_vms) {
                # VMS pipe bug inserts blank lines.
                my $l2 = <$results>;
                if ($l2 =~ /^\s*$/) {
@@ -694,9 +829,12 @@ EOT
                }
            }
        }
+       my  @junk = <$results>;  # dump remaining output to prevent SIGPIPE
+                                # (so far happens only on os390)
        close $results;
+       undef @junk;
 
-       if (not $failure) {
+       if (not defined $failure) {
            $failure = 'FAILED--no leader found' unless $seen_leader;
        }
 
@@ -705,19 +843,21 @@ EOT
        if ($type eq 'deparse' && !$ENV{KEEP_DEPARSE_FILES}) {
            unlink "./$test.dp";
        }
-       if (not $failure and $next != $max) {
+       if (not defined $failure and $next != $max) {
            $failure="FAILED--expected $max tests, saw $next";
        }
 
-       if (not $failure and $? ) {     # don't mask a test failure
+       if( !defined $failure  # don't mask a test failure
+           and $? )
+       {
            $failure = "FAILED--non-zero wait status: $?";
        }
 
        # Deparse? Should it have passed or failed?
        if ($type eq 'deparse' && $test =~ $deparse_failures) {
            if (!$failure) {
-               # Wait, it didn't fail? Great news! Tell someone!
-               $failure = "FAILED--all tests passed but test should have failed";
+               # Wait, it didn't fail? Great news!
+               push @unexpected_pass, $test;
            } else {
                # Bah, still failing. Mask it.
                print "${te}skipped\n";
@@ -726,7 +866,7 @@ EOT
            }
        }
 
-       if ($failure) {
+       if (defined $failure) {
            print "${te}$failure\n";
            $::bad_files = $::bad_files + 1;
            if ($test =~ /^base/ && ! defined &DynaLoader::boot_DynaLoader) {
@@ -777,6 +917,17 @@ EOT
        for my $test ( sort keys %failed_tests ) {
            print "\t$test\n";
        }
+
+       if (@unexpected_pass) {
+           print <<EOF;
+
+The following scripts were expected to fail under -deparse (at least
+according to $deparse_skip_file), but unexpectedly succeeded:
+EOF
+           print "\t$_\n" for sort @unexpected_pass;
+           print "\n";
+       }
+
        warn <<'SHRDLU_1';
 ### Since not all tests were successful, you may want to run some of
 ### them individually and examine any diagnostic messages they produce.
@@ -787,7 +938,7 @@ SHRDLU_1
 ###   ./perl harness
 ### in the 't' directory since most (>=80%) of the tests succeeded.
 SHRDLU_2
-       if (eval {require Config; import Config; 1}) {
+       if (eval {require Config; Config->import; 1}) {
            if ($::Config{usedl} && (my $p = $::Config{ldlibpthname})) {
                warn <<SHRDLU_3;
 ### You may have to set your dynamic library search path,
@@ -813,6 +964,7 @@ SHRDLU_5
            }
        }
     }
+    printf "Elapsed: %d sec\n", time() - $t0;
     my ($user,$sys,$cuser,$csys) = times;
     my $tot = sprintf("u=%.2f  s=%.2f  cu=%.2f  cs=%.2f  scripts=%d  tests=%d",
                      $user,$sys,$cuser,$csys,$tested_files,$totmax);
@@ -824,7 +976,9 @@ SHRDLU_5
            # relative path must account for that, ie ../../perf
            # points to dir next to source tree.
            require Storable;
-           my $fn = "$show_elapsed_time/$::tstamp.ttimes";
+           my @dt = localtime;
+           $dt[5] += 1900; $dt[4] += 1; # fix year, month
+           my $fn = "$show_elapsed_time/".join('-', @dt[5,4,3,2,1]).".ttimes";
            Storable::store({ perf => \%timings,
                              gather_conf_platform_info(),
                              total => $tot,
@@ -854,7 +1008,7 @@ sub gather_conf_platform_info {
        @platform = grep /name|cpu/, <$fh>;
        chomp $_ for @platform;
     }
-    unshift @platform, $^O;
+    unshift @platform, $OS;
 
     return (
        conf => \%conf,
@@ -944,16 +1098,20 @@ sub _cleanup_valgrind {
        unlink _find_files('cachegrind.out.\d+$',
                     qw ( ../t ../cpan ../ext ../dist/ ));
     }
+    elsif ($$toolnm eq 'valgrind') {
+       # Remove empty, hence non-error, output files
+       unlink grep { -z } _find_files('valgrind-current',
+                    qw ( ../t ../cpan ../ext ../dist/ ));
+    }
 }
 
 # Generate regexps of known bad filenames / skips from Porting/deparse-skips.txt
-my $in;
 
 sub _process_deparse_config {
     my @deparse_failures;
     my @deparse_skips;
 
-    my $f = '../Porting/deparse-skips.txt';
+    my $f = $deparse_skip_file;
 
     my $skips;
     if (!open($skips, '<', $f)) {
@@ -961,6 +1119,7 @@ sub _process_deparse_config {
         return;
     }
 
+    my $in;
     while(<$skips>) {
         if (/__DEPARSE_FAILURES__/) {
             $in = \@deparse_failures; next;
@@ -976,6 +1135,7 @@ sub _process_deparse_config {
         next unless $_;
 
         push @$in, $_;
+       warn "WARNING: $f:$.: excluded file doesn't exist: $_\n" unless -f $_;
     }
 
     for my $f (@deparse_failures, @deparse_skips) {