File Coverage

blib/lib/FindBin/Real.pm
Criterion Covered Total %
statement 52 66 78.7
branch 21 46 45.6
condition 8 35 22.8
subroutine 15 15 100.0
pod 7 8 87.5
total 103 170 60.5


line stmt bran cond sub pod time code
1             # FindBin/Real.pm
2             #
3             # Copyright (c) 1995 Graham Barr & Nick Ing-Simmons. All rights reserved.
4             # Copyright (c) 2003-2005 Serguei Trouchelle. All rights reserved.
5             #
6             # This program is free software; you can redistribute it and/or modify it
7             # under the same terms as Perl itself.
8            
9             # History:
10             # 1.05 2007/02/04 Quality update (Test::Pod, Test::Pod::Coverage)
11             # 1.04 2005/02/07 Refactured version. About +50% in performance.
12             # Version is corrected to $FindBin::Real::VERSION.
13             # Fixed problem with Dir/RealDir
14             # Some tests added.
15             # 1.03 2004/02/15 Added BinDepth() function
16             # (Suggested by Tielman de Villiers)
17             # 1.02 2003/08/10 Fixed bug in Makefile.PM (Findbin -> FindBin)
18             # ^M symbols are removed from sources
19             # (Thanks to Mike Castle)
20             # 1.01 2003/08/08 Added some tests and README
21             # 1.00 2003/08/06 Initial revision
22            
23             =head1 NAME
24            
25             FindBin::Real - Locate directory of original perl script
26            
27             =head1 SYNOPSIS
28            
29             use FindBin::Real;
30             use lib FindBin::Real::Bin() . '/../lib';
31            
32             or
33            
34             use FindBin::Real qw(Bin);
35             use lib Bin() . '/../lib';
36            
37             or
38            
39             # Run from /usr/bin/www/some/path/ or /usr/bin/www/some/other/path or any
40             use FindBin::Real qw(BinDepth);
41             use lib BinDepth(3) . '/lib';
42             # And always got /usr/bin/www/lib !
43            
44             =head1 DESCRIPTION
45            
46             Locates the full path to the script bin directory to allow the use
47             of paths relative to the bin directory.
48            
49             This allows a user to setup a directory tree for some software with
50             directories ErootE/bin and ErootE/lib and then the above example will allow
51             the use of modules in the lib directory without knowing where the software
52             tree is installed.
53            
54             If perl is invoked using the B<-e> option or the perl script is read from
55             C then FindBin sets both C and C return values to the current
56             directory.
57            
58             =head1 EXPORTABLE FUNCTIONS
59            
60             =head2 Bin
61            
62             - path to bin directory from where script was invoked
63            
64             =head2 Script
65            
66             - basename of script from which perl was invoked
67            
68             =head2 RealBin
69            
70             - Bin() with all links resolved
71            
72             =head2 RealScript
73            
74             - Script() with all links resolved
75            
76             =head2 BinDepth(n)
77            
78             - path to n-level parent directory
79            
80             =head2 Dir()
81            
82             - the same as Bin()
83            
84             =head2 RealDir()
85            
86             - the same as RealBin()
87            
88             =head1 KNOWN ISSUES
89            
90             If there are two modules using C from different directories
91             under the same interpreter, this WOULD work. Since C uses
92             functions instead of C block in C, it'll be executed on every script,
93             and all callers will get it right. This module can be used under mod_perl and other persistent
94             Perl environments, where you shouldn't use C.
95            
96             =head1 KNOWN BUGS
97            
98             If perl is invoked as
99            
100             perl filename
101            
102             and I does not have executable rights and a program called I
103             exists in the users C<$ENV{PATH}> which satisfies both B<-x> and B<-T> then FindBin
104             assumes that it was invoked via the C<$ENV{PATH}>.
105            
106             Workaround is to invoke perl as
107            
108             perl ./filename
109            
110             =head1 AUTHORS
111            
112             Serguei Trouchelle EFE
113            
114             FindBin::Real uses code from FindBin module, which was written by
115            
116             Graham Barr EFE
117             Nick Ing-Simmons EFE
118            
119             =head1 COPYRIGHT
120            
121             Copyright (c) 1995 Graham Barr & Nick Ing-Simmons. All rights reserved.
122             Copyright (c) 2003-2005 Serguei Trouchelle. All rights reserved.
123            
124             This program is free software; you can redistribute it and/or modify it
125             under the same terms as Perl itself.
126            
127             =cut
128            
129             package FindBin::Real;
130 8     8   109713 use Carp;
  8         22  
  8         665  
131             require 5.006;
132             require Exporter;
133 8     8   45 use Cwd qw(getcwd abs_path);
  8         12  
  8         438  
134 8     8   50 use Config;
  8         45  
  8         412  
135 8     8   41 use File::Basename;
  8         13  
  8         572  
136 8     8   42 use File::Spec;
  8         14  
  8         182  
137            
138 8     8   38 use strict;
  8         13  
  8         340  
139 8     8   38 use warnings;
  8         15  
  8         8860  
140            
141             our @EXPORT_OK = qw(Bin Script RealBin RealScript Dir RealDir BinDepth);
142             our %EXPORT_TAGS = (ALL => [qw(Bin Script RealBin RealScript Dir RealDir BinDepth)]);
143             our @ISA = qw(Exporter);
144            
145             $FindBin::Real::VERSION = "1.05";
146            
147             my $keyBin = 1;
148             my $keyScript = 2;
149             my $keyRealBin = 3;
150             my $keyRealScript = 4;
151            
152             #
153             # mastermind
154             #
155             sub mastermind {
156 9   50 9 0 36 my $meth = shift || die 'Invalid call to mastermind';
157            
158 9 50 33     117 if ($0 eq '-e' || $0 eq '-') {
159 0 0 0     0 return getcwd() if $meth == $keyBin || $meth == $keyRealBin;
160 0 0 0     0 return $0 if $meth == $keyScript || $meth == $keyRealScript;
161             }
162 9 50       82 if ($^O eq 'VMS') {
163             # ($Bin,$Script) = VMS::Filespec::rmsexpand($0) =~ /(.*\])(.*)/s;
164 0 0 0     0 return VMS::Filespec::rmsexpand($0) =~ /(.*\])/s if $meth == $keyBin || $meth == $keyRealBin;
165 0 0 0     0 return VMS::Filespec::rmsexpand($0) =~ /.*\](.*)/s if $meth == $keyScript || $meth == $keyRealScript;
166             }
167            
168 9         33 my ($Bin, $Script, $RealBin, $RealScript, $Dir, $RealDir);
169 9         129 my $script = $0;
170            
171 9   33     64 my $dosish = ($^O eq 'MSWin32' or $^O eq 'os2');
172 9 50 33     278 unless(($script =~ m#/# || ($dosish && $script =~ m#\\#))
      33        
173             && -f $script)
174             {
175 0         0 my $dir;
176 0         0 foreach $dir (File::Spec->path)
177             {
178 0         0 my $scr = File::Spec->catfile($dir, $script);
179 0 0 0     0 if(-r $scr && (!$dosish || -x _))
      0        
180             {
181 0         0 $script = $scr;
182            
183 0 0       0 if (-f $0)
184             {
185             # $script has been found via PATH but perl could have
186             # been invoked as 'perl file'. Do a dumb check to see
187             # if $script is a perl program, if not then $script = $0
188             #
189             # well we actually only check that it is an ASCII file
190             # we know its executable so it is probably a script
191             # of some sort.
192            
193 0 0       0 $script = $0 unless(-T $script);
194             }
195 0         0 last;
196             }
197             }
198             }
199            
200 9 50       117 croak("Cannot find current script '$0'") unless(-f $script);
201            
202             # Ensure $script contains the complete path incase we C
203            
204 9 50       327 $script = File::Spec->catfile(getcwd(), $script)
205             unless File::Spec->file_name_is_absolute($script);
206            
207 9 100 100     64 if ($meth == $keyBin or $meth == $keyScript) {
208 6         168 ($Script,$Bin) = fileparse($script);
209             } else {
210             # RealBin/RealScript:
211             # Resolve $script if it is a link
212 3         7 while(1) {
213 3         57 my $linktext = readlink($script);
214            
215 3         96 ($RealScript,$RealBin) = fileparse($script);
216 3 50       14 last unless defined $linktext;
217            
218 0 0       0 $script = (File::Spec->file_name_is_absolute($linktext))
219             ? $linktext
220             : File::Spec->catfile($RealBin, $linktext);
221             }
222             }
223             # Get absolute paths to directories
224 9 100       377 $Bin = abs_path($Bin) if $Bin;
225 9 100       208 $RealBin = abs_path($RealBin) if $RealBin;
226            
227 9 100       49 return $Bin if $meth == $keyBin;
228 4 100       28 return $Script if $meth == $keyScript;
229 3 100       24 return $RealBin if $meth == $keyRealBin;
230 1 50       10 return $RealScript if $meth == $keyRealScript;
231             }
232            
233             sub Bin {
234 4     4 1 17 return mastermind($keyBin);
235             }
236            
237             sub Script {
238 1     1 1 10 return mastermind($keyScript);
239             }
240            
241             sub RealBin {
242 1     1 1 14 return mastermind($keyRealBin);
243             }
244            
245             sub RealScript {
246 1     1 1 10 return mastermind($keyRealScript);
247             }
248            
249             sub Dir {
250 1     1 1 11 return mastermind($keyBin);
251             }
252            
253             sub RealDir {
254 1     1 1 9 return mastermind($keyRealBin);
255             }
256            
257             sub BinDepth($) {
258 3     3 1 716 my $depth = shift;
259 3         8 my $Bin = Bin();
260 3 50       12 return $Bin unless $depth =~ /\d+/;
261 3 50       72 return $1 . $2 if $Bin =~ m!(.*?)((/[^/]+?){$depth})/!;
262 0           return $Bin;
263             }
264            
265             1; # Keep require happy
266            
267