1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
#line 1
package File::Which;
use strict;
use warnings;
use Exporter ();
use File::Spec ();
# ABSTRACT: Perl implementation of the which utility as an API
our $VERSION = '1.22'; # VERSION
our @ISA = 'Exporter';
our @EXPORT = 'which';
our @EXPORT_OK = 'where';
use constant IS_VMS => ($^O eq 'VMS');
use constant IS_MAC => ($^O eq 'MacOS');
use constant IS_DOS => ($^O eq 'MSWin32' or $^O eq 'dos' or $^O eq 'os2');
use constant IS_CYG => ($^O eq 'cygwin' || $^O eq 'msys');
# For Win32 systems, stores the extensions used for
# executable files
# For others, the empty string is used
# because 'perl' . '' eq 'perl' => easier
my @PATHEXT = ('');
if ( IS_DOS ) {
# WinNT. PATHEXT might be set on Cygwin, but not used.
if ( $ENV{PATHEXT} ) {
push @PATHEXT, split ';', $ENV{PATHEXT};
} else {
# Win9X or other: doesn't have PATHEXT, so needs hardcoded.
push @PATHEXT, qw{.com .exe .bat};
}
} elsif ( IS_VMS ) {
push @PATHEXT, qw{.exe .com};
} elsif ( IS_CYG ) {
# See this for more info
# http://cygwin.com/cygwin-ug-net/using-specialnames.html#pathnames-exe
push @PATHEXT, qw{.exe .com};
}
sub which {
my ($exec) = @_;
return undef unless defined $exec;
return undef if $exec eq '';
my $all = wantarray;
my @results = ();
# check for aliases first
if ( IS_VMS ) {
my $symbol = `SHOW SYMBOL $exec`;
chomp($symbol);
unless ( $? ) {
return $symbol unless $all;
push @results, $symbol;
}
}
if ( IS_MAC ) {
my @aliases = split /\,/, $ENV{Aliases};
foreach my $alias ( @aliases ) {
# This has not been tested!!
# PPT which says MPW-Perl cannot resolve `Alias $alias`,
# let's just hope it's fixed
if ( lc($alias) eq lc($exec) ) {
chomp(my $file = `Alias $alias`);
last unless $file; # if it failed, just go on the normal way
return $file unless $all;
push @results, $file;
# we can stop this loop as if it finds more aliases matching,
# it'll just be the same result anyway
last;
}
}
}
return $exec
if !IS_VMS and !IS_MAC and !IS_DOS and $exec =~ /\// and -f $exec and -x $exec;
my @path = File::Spec->path;
if ( IS_DOS or IS_VMS or IS_MAC ) {
unshift @path, File::Spec->curdir;
}
foreach my $base ( map { File::Spec->catfile($_, $exec) } @path ) {
for my $ext ( @PATHEXT ) {
my $file = $base.$ext;
# We don't want dirs (as they are -x)
next if -d $file;
if (
# Executable, normal case
-x _
or (
# MacOS doesn't mark as executable so we check -e
IS_MAC
||
(
( IS_DOS or IS_CYG )
and
grep {
$file =~ /$_\z/i
} @PATHEXT[1..$#PATHEXT]
)
# DOSish systems don't pass -x on
# non-exe/bat/com files. so we check -e.
# However, we don't want to pass -e on files
# that aren't in PATHEXT, like README.
and -e _
)
) {
return $file unless $all;
push @results, $file;
}
}
}
if ( $all ) {
return @results;
} else {
return undef;
}
}
sub where {
# force wantarray
my @res = which($_[0]);
return @res;
}
1;
__END__
#line 336
|