Blame t/common.pm

Packit 0bf95d
use strict;
Packit 0bf95d
Packit 0bf95d
# Shared defs for test programs
Packit 0bf95d
Packit 0bf95d
# Paths. Must make case-insensitive.
Packit 0bf95d
use File::Temp qw(tempfile tempdir);
Packit 0bf95d
use File::Spec;
Packit 0bf95d
BEGIN { mkdir 'testdir' }
Packit 0bf95d
use constant TESTDIR => do {
Packit 0bf95d
    my $tmpdir = File::Spec->abs2rel(tempdir(DIR => 'testdir', CLEANUP => 1));
Packit 0bf95d
    $tmpdir =~ s!\\!/!g if $^O eq 'MSWin32';
Packit 0bf95d
    $tmpdir
Packit 0bf95d
};
Packit 0bf95d
use constant INPUTZIP =>
Packit 0bf95d
  (tempfile('testin-XXXXX', SUFFIX => '.zip', TMPDIR => 1, $^O eq 'MSWin32' ? () : (UNLINK => 1)))[1];
Packit 0bf95d
use constant OUTPUTZIP =>
Packit 0bf95d
  (tempfile('testout-XXXXX', SUFFIX => '.zip', TMPDIR => 1, $^O eq 'MSWin32' ? () : (UNLINK => 1)))[1];
Packit 0bf95d
Packit 0bf95d
# Do we have the 'zip' and 'unzip' programs?
Packit 0bf95d
# Embed a copy of the module, rather than adding a dependency
Packit 0bf95d
BEGIN {
Packit 0bf95d
Packit 0bf95d
    package File::Which;
Packit 0bf95d
Packit 0bf95d
    use File::Spec;
Packit 0bf95d
Packit 0bf95d
    my $Is_VMS   = ($^O eq 'VMS');
Packit 0bf95d
    my $Is_MacOS = ($^O eq 'MacOS');
Packit 0bf95d
    my $Is_DOSish =
Packit 0bf95d
      (($^O eq 'MSWin32') or ($^O eq 'dos') or ($^O eq 'os2'));
Packit 0bf95d
Packit 0bf95d
    # For Win32 systems, stores the extensions used for
Packit 0bf95d
    # executable files
Packit 0bf95d
    # For others, the empty string is used
Packit 0bf95d
    # because 'perl' . '' eq 'perl' => easier
Packit 0bf95d
    my @path_ext = ('');
Packit 0bf95d
    if ($Is_DOSish) {
Packit 0bf95d
        if ($ENV{PATHEXT} and $Is_DOSish)
Packit 0bf95d
        {    # WinNT. PATHEXT might be set on Cygwin, but not used.
Packit 0bf95d
            push @path_ext, split ';', $ENV{PATHEXT};
Packit 0bf95d
        } else {
Packit 0bf95d
            push @path_ext, qw(.com .exe .bat)
Packit 0bf95d
              ;    # Win9X or other: doesn't have PATHEXT, so needs hardcoded.
Packit 0bf95d
        }
Packit 0bf95d
    } elsif ($Is_VMS) {
Packit 0bf95d
        push @path_ext, qw(.exe .com);
Packit 0bf95d
    }
Packit 0bf95d
Packit 0bf95d
    sub which {
Packit 0bf95d
        my ($exec) = @_;
Packit 0bf95d
Packit 0bf95d
        return undef unless $exec;
Packit 0bf95d
Packit 0bf95d
        my $all     = wantarray;
Packit 0bf95d
        my @results = ();
Packit 0bf95d
Packit 0bf95d
        # check for aliases first
Packit 0bf95d
        if ($Is_VMS) {
Packit 0bf95d
            my $symbol = `SHOW SYMBOL $exec`;
Packit 0bf95d
            chomp($symbol);
Packit 0bf95d
            if (!$?) {
Packit 0bf95d
                return $symbol unless $all;
Packit 0bf95d
                push @results, $symbol;
Packit 0bf95d
            }
Packit 0bf95d
        }
Packit 0bf95d
        if ($Is_MacOS) {
Packit 0bf95d
            my @aliases = split /\,/, $ENV{Aliases};
Packit 0bf95d
            foreach my $alias (@aliases) {
Packit 0bf95d
Packit 0bf95d
                # This has not been tested!!
Packit 0bf95d
                # PPT which says MPW-Perl cannot resolve `Alias $alias`,
Packit 0bf95d
                # let's just hope it's fixed
Packit 0bf95d
                if (lc($alias) eq lc($exec)) {
Packit 0bf95d
                    chomp(my $file = `Alias $alias`);
Packit 0bf95d
                    last unless $file; # if it failed, just go on the normal way
Packit 0bf95d
                    return $file unless $all;
Packit 0bf95d
                    push @results, $file;
Packit 0bf95d
Packit 0bf95d
                   # we can stop this loop as if it finds more aliases matching,
Packit 0bf95d
                   # it'll just be the same result anyway
Packit 0bf95d
                    last;
Packit 0bf95d
                }
Packit 0bf95d
            }
Packit 0bf95d
        }
Packit 0bf95d
Packit 0bf95d
        my @path = File::Spec->path();
Packit 0bf95d
        unshift @path, File::Spec->curdir if $Is_DOSish or $Is_VMS or $Is_MacOS;
Packit 0bf95d
Packit 0bf95d
        for my $base (map { File::Spec->catfile($_, $exec) } @path) {
Packit 0bf95d
            for my $ext (@path_ext) {
Packit 0bf95d
                my $file = $base . $ext;
Packit 0bf95d
Packit 0bf95d
                # print STDERR "$file\n";
Packit 0bf95d
Packit 0bf95d
                if (
Packit 0bf95d
                    (
Packit 0bf95d
                        -x $file or    # executable, normal case
Packit 0bf95d
                        (
Packit 0bf95d
                            $Is_MacOS
Packit 0bf95d
                            || # MacOS doesn't mark as executable so we check -e
Packit 0bf95d
                            (
Packit 0bf95d
                                $Is_DOSish
Packit 0bf95d
                                and grep { $file =~ /$_$/i }
Packit 0bf95d
                                @path_ext[1 .. $#path_ext])
Packit 0bf95d
Packit 0bf95d
                    # DOSish systems don't pass -x on non-exe/bat/com files.
Packit 0bf95d
                    # so we check -e. However, we don't want to pass -e on files
Packit 0bf95d
                    # that aren't in PATHEXT, like README.
Packit 0bf95d
                            and -e _))
Packit 0bf95d
                    and !-d _)
Packit 0bf95d
                {    # and finally, we don't want dirs to pass (as they are -x)
Packit 0bf95d
Packit 0bf95d
            # print STDERR "-x: ", -x $file, " -e: ", -e _, " -d: ", -d _, "\n";
Packit 0bf95d
Packit 0bf95d
                    return $file unless $all;
Packit 0bf95d
                    push @results, $file;    # Make list to return later
Packit 0bf95d
                }
Packit 0bf95d
            }
Packit 0bf95d
        }
Packit 0bf95d
Packit 0bf95d
        if ($all) {
Packit 0bf95d
            return @results;
Packit 0bf95d
        } else {
Packit 0bf95d
            return undef;
Packit 0bf95d
        }
Packit 0bf95d
    }
Packit 0bf95d
}
Packit 0bf95d
use constant HAVEZIP   => !!File::Which::which('zip');
Packit 0bf95d
use constant HAVEUNZIP => !!File::Which::which('unzip');
Packit 0bf95d
Packit 0bf95d
use constant ZIP     => 'zip ';
Packit 0bf95d
use constant ZIPTEST => 'unzip -t ';
Packit 0bf95d
Packit 0bf95d
# 300-character test string
Packit 0bf95d
use constant TESTSTRING => join("\n", 1 .. 102) . "\n";
Packit 0bf95d
use constant TESTSTRINGLENGTH => length(TESTSTRING);
Packit 0bf95d
Packit 0bf95d
use Archive::Zip ();
Packit 0bf95d
Packit 0bf95d
# CRC-32 should be ac373f32
Packit 0bf95d
use constant TESTSTRINGCRC => Archive::Zip::computeCRC32(TESTSTRING);
Packit 0bf95d
Packit 0bf95d
# This is so that it will work on other systems.
Packit 0bf95d
use constant CAT     => $^X . ' -pe "BEGIN{binmode(STDIN);binmode(STDOUT)}"';
Packit 0bf95d
use constant CATPIPE => '| ' . CAT . ' >';
Packit 0bf95d
Packit 0bf95d
use vars qw($zipWorks $testZipDoesntWork $catWorks);
Packit 0bf95d
Packit 0bf95d
# Run ZIPTEST to test a zip file.
Packit 0bf95d
sub testZip {
Packit 0bf95d
    my $zipName = shift || OUTPUTZIP;
Packit 0bf95d
    if ($testZipDoesntWork) {
Packit 0bf95d
        return wantarray ? (0, '') : 0;
Packit 0bf95d
    }
Packit 0bf95d
    my $cmd = ZIPTEST . $zipName . ($^O eq 'MSWin32' ? '' : ' 2>&1');
Packit 0bf95d
    my $zipout = `$cmd`;
Packit 0bf95d
    return wantarray ? ($?, $zipout) : $?;
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
# Return the crc-32 of the given file (0 if empty or error)
Packit 0bf95d
sub fileCRC {
Packit 0bf95d
    my $fileName = shift;
Packit 0bf95d
    local $/ = undef;
Packit 0bf95d
    my $fh = IO::File->new($fileName, "r");
Packit 0bf95d
    binmode($fh);
Packit 0bf95d
    return 0 if not defined($fh);
Packit 0bf95d
    my $contents = <$fh>;
Packit 0bf95d
    return Archive::Zip::computeCRC32($contents);
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
#--------- check to see if cat works
Packit 0bf95d
Packit 0bf95d
sub testCat {
Packit 0bf95d
    my $fh = IO::File->new(CATPIPE . OUTPUTZIP);
Packit 0bf95d
    binmode($fh);
Packit 0bf95d
    my $testString = pack('C256', 0 .. 255);
Packit 0bf95d
    my $testCrc = Archive::Zip::computeCRC32($testString);
Packit 0bf95d
    $fh->write($testString, length($testString)) or return 0;
Packit 0bf95d
    $fh->close();
Packit 0bf95d
    (-f OUTPUTZIP) or return 0;
Packit 0bf95d
    my @stat = stat(OUTPUTZIP);
Packit 0bf95d
    $stat[7] == length($testString) or return 0;
Packit 0bf95d
    fileCRC(OUTPUTZIP) == $testCrc  or return 0;
Packit 0bf95d
    unlink(OUTPUTZIP);
Packit 0bf95d
    return 1;
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
BEGIN {
Packit 0bf95d
    $catWorks = testCat();
Packit 0bf95d
    unless ($catWorks) {
Packit 0bf95d
        warn('warning: ', CAT, " doesn't seem to work, may skip some tests");
Packit 0bf95d
    }
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
#--------- check to see if zip works (and make INPUTZIP)
Packit 0bf95d
Packit 0bf95d
BEGIN {
Packit 0bf95d
    unlink(INPUTZIP);
Packit 0bf95d
Packit 0bf95d
    # Do we have zip installed?
Packit 0bf95d
    if (HAVEZIP) {
Packit 0bf95d
        my $cmd = ZIP . INPUTZIP . ' *' . ($^O eq 'MSWin32' ? '' : ' 2>&1');
Packit 0bf95d
        my $zipout = `$cmd`;
Packit 0bf95d
        $zipWorks = not $?;
Packit 0bf95d
        unless ($zipWorks) {
Packit 0bf95d
            warn('warning: ', ZIP,
Packit 0bf95d
                " doesn't seem to work, may skip some tests");
Packit 0bf95d
        }
Packit 0bf95d
    }
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
#--------- check to see if unzip -t works
Packit 0bf95d
Packit 0bf95d
BEGIN {
Packit 0bf95d
    $testZipDoesntWork = 1;
Packit 0bf95d
    if (HAVEUNZIP) {
Packit 0bf95d
        my ($status, $zipout) = do { local $testZipDoesntWork = 0; testZip(INPUTZIP) };
Packit 0bf95d
            # 9 * 256 = 2304 - the specified zipfiles were not found
Packit 0bf95d
        $testZipDoesntWork = (($status == 0 || $status == 2304) ? 0 : 1);
Packit 0bf95d
Packit 0bf95d
        # Again, on Win32 no big surprise if this doesn't work
Packit 0bf95d
        if ($testZipDoesntWork) {
Packit 0bf95d
            warn('warning: ', ZIPTEST,
Packit 0bf95d
                " doesn't seem to work, may skip some tests");
Packit 0bf95d
        }
Packit 0bf95d
    }
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
sub passthrough
Packit 0bf95d
{
Packit 0bf95d
    my $fromFile = shift ;
Packit 0bf95d
    my $toFile = shift ;
Packit 0bf95d
    my $action = shift ;
Packit 0bf95d
Packit 0bf95d
    my $z = Archive::Zip->new; 
Packit 0bf95d
    $z->read($fromFile);
Packit 0bf95d
    if ($action)
Packit 0bf95d
    {
Packit 0bf95d
        for my $member($z->members())
Packit 0bf95d
        {
Packit 0bf95d
            &$action($member) ; 
Packit 0bf95d
        }
Packit 0bf95d
    }
Packit 0bf95d
    $z->writeToFileNamed($toFile);
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
sub readFile
Packit 0bf95d
{
Packit 0bf95d
    my $name = shift ;
Packit 0bf95d
    local $/;
Packit 0bf95d
    open F, "<$name"
Packit 0bf95d
        or die "Cannot open $name: $!\n";
Packit 0bf95d
    my $data = <F>;
Packit 0bf95d
    close F ;
Packit 0bf95d
    return $data;
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
1;