File Coverage

blib/lib/Psh/Util.pm
Criterion Covered Total %
statement 3 146 2.0
branch 0 84 0.0
condition 0 52 0.0
subroutine 1 18 5.5
pod 0 16 0.0
total 4 316 1.2


line stmt bran cond sub pod time code
1             package Psh::Util;
2              
3 1     1   6 use strict;
  1         2  
  1         2077  
4              
5             require Psh::OS;
6              
7             %Psh::Util::command_hash=();
8             %Psh::Util::path_hash=();
9              
10             sub print_warning
11             {
12 0     0 0   print STDERR @_;
13             }
14              
15             #
16             # Print unclassified debug output
17             #
18             sub print_debug
19             {
20 0 0 0 0 0   print STDERR @_ if $Psh::debugging && $Psh::debugging =~ /o/;
21             }
22              
23             #
24             # Print classified debug output
25             #
26             sub print_debug_class
27             {
28 0     0 0   my $class= shift;
29 0 0 0       print STDERR @_ if $Psh::debugging and
      0        
30             ($Psh::debugging eq '1' or
31             $Psh::debugging =~ /$class/);
32             }
33              
34             sub print_error
35             {
36 0     0 0   print STDERR @_;
37             }
38              
39             #
40             # print_i18n( stream, key, args)
41             # print_out_i18n( key, args)
42             # print_error_i18n( key, args)
43             #
44             # The print..._i18n suite of functions will fetch the
45             # text from the %text hash, replace %1 with the first arg,
46             # %2 with the second and so on and then print it out
47             #
48              
49             sub _print_i18n
50             {
51 0     0     my( $stream, $text, @rest) = @_;
52 0 0         return unless $stream;
53 0           $text= Psh::Locale::get_text($text);
54 0           for( my $i=1; $i<=@rest; $i++)
55             {
56 0           $text=~ s/\%$i/$rest[$i-1]/g;
57             }
58 0           print $stream $text;
59             }
60              
61              
62             sub print_error_i18n
63             {
64 0     0 0   _print_i18n(*STDERR,@_);
65             }
66              
67             sub print_warning_i18n
68             {
69 0     0 0   _print_i18n(*STDERR,@_);
70             }
71              
72             sub print_out_i18n
73             {
74 0     0 0   _print_i18n(*STDOUT,@_);
75             }
76              
77             sub print_out
78             {
79 0     0 0   print STDOUT @_;
80             }
81              
82             # Copied from readline.pl - pretty prints a list in columns
83             sub print_list
84             {
85 0     0 0   my @list= @_;
86 0 0         return unless @list;
87 0           my ($lines, $columns, $mark, $index);
88              
89             ## find width of widest entry
90 0           my $maxwidth = 0;
91 0           my $screen_width=$ENV{COLUMNS};
92              
93 0 0 0       if (ref $list[0] and ref $list[0] eq 'ARRAY') {
94 0           $maxwidth= $list[1];
95 0           @list= @{$list[0]};
  0            
96             }
97              
98 0 0         unless ($maxwidth) {
99 0   0       grep(length > $maxwidth && ($maxwidth = length), @list);
100             }
101 0           $maxwidth++;
102              
103 0 0         $columns = $maxwidth >= $screen_width?1:int($screen_width / $maxwidth);
104              
105             ## if there's enough margin to interspurse among the columns, do so.
106 0           $maxwidth += int(($screen_width % $maxwidth) / $columns);
107              
108 0           $lines = int((@list + $columns - 1) / $columns);
109 0           $columns-- while ((($lines * $columns) - @list + 1) > $lines);
110              
111 0           $mark = $#list - $lines;
112 0           for (my $l = 0; $l < $lines; $l++) {
113 0           for ($index = $l; $index <= $mark; $index += $lines) {
114 0           my $tmp= my $item= $list[$index];
115 0           $tmp=~ s/\001(.*?)\002//g;
116 0           $item=~s/\001//g;
117 0           $item=~s/\002//g;
118 0           my $diff= length($item)-length($tmp);
119 0           my $dispsize= $maxwidth+$diff;
120 0           print_out(sprintf("%-${dispsize}s", $item));
121             }
122 0 0         if ($index<=$#list) {
123 0           my $item= $list[$index];
124 0           $item=~s/\001//g; $item=~s/\002//g;
  0            
125 0           print_out($item);
126             }
127 0           print_out("\n");
128             }
129             }
130              
131             sub abs_path {
132 0     0 0   my $dir= shift;
133 0 0         return undef unless $dir;
134 0 0         return $Psh::Util::path_hash{$dir} if $Psh::Util::path_hash{$dir};
135 0           my $result= Psh::OS::abs_path($dir);
136 0 0         unless ($result) {
137 0 0         if ($dir eq '~') {
    0          
    0          
138 0           $result= Psh::OS::get_home_dir();
139             } elsif ( substr($dir,0,2) eq '~/') {
140 0           substr($dir,0,1)= Psh::OS::get_home_dir();
141             } elsif ( substr($dir,0,1) eq '~' ) {
142 0           my $fs= $Psh::OS::FILE_SEPARATOR;
143 0           my ($user)= $dir=~/^\~(.*?)$fs/;
144 0 0         if ($user) {
145 0           substr($dir,0,length($user)+1)= Psh::OS::get_home_dir($user);
146             }
147             }
148 0 0         unless ($result) {
149 0           my $tmp= Psh::OS::rel2abs($dir,$ENV{PWD});
150              
151 0           my $old= $ENV{PWD};
152 0 0 0       if ($tmp and -r $tmp) {
153 0 0 0       if (-d $tmp and -x _) {
154 0 0         if ( CORE::chdir($tmp)) {
155 0           $result = Psh::OS::getcwd_psh();
156 0 0         if (!CORE::chdir($old)) {
157 0           print STDERR "Could not change directory back to $old!\n";
158 0           CORE::chdir(Psh::OS::get_home_dir())
159             }
160             }
161             } else {
162 0           $result= $tmp;
163             }
164             }
165             # if ($tmp and !$result) {
166             # local $^W=0;
167             # local $SIG{__WARN__}= {};
168             # eval {
169             # $result= Cwd::abs_path($tmp);
170             # };
171             # print_debug_class('e',"(abs_path) Error: $@") if $@;
172             # }
173 0 0         return undef unless $result;
174             }
175 0 0         if ($result) {
176 0 0         $result.='/' unless $result=~ m:[/\\]:; # abs_path strips / from letter: on Win
177             }
178             }
179 0 0         $Psh::Util::path_hash{$dir}= $result if Psh::OS::file_name_is_absolute($dir);
180 0           return $result;
181             }
182              
183             sub recalc_absed_path {
184 0     0 0   @Psh::absed_path = ();
185 0           %Psh::Util::command_hash = ();
186              
187 0           my @path = split($Psh::OS::PATH_SEPARATOR, $ENV{PATH});
188              
189 0           eval {
190 0           foreach my $dir (@path) {
191 0 0         next unless $dir;
192 0           my $dir= Psh::Util::abs_path($dir);
193 0 0 0       next unless -r $dir and -x _;
194 0           push @Psh::absed_path, $dir;
195             }
196             };
197 0 0         print_debug_class('e',"(recalc_absed_path) Error: $@") if $@;
198             # Without the eval Psh might crash if the directory
199             # does not exist
200             }
201              
202             #
203             # string which(string FILENAME)
204             #
205             # search for an occurrence of FILENAME in the current path as given by
206             # $ENV{PATH}. Return the absolute filename if found, or undef if not.
207             #
208              
209             {
210             #
211             # "static variables" for which() :
212             #
213              
214             my $last_path_cwd = '';
215             my $FS=$Psh::OS::FILE_SEPARATOR;
216             my $tmp= quotemeta($FS);
217             my $re1="$tmp";
218             my $re2="^(.*)$tmp([^$tmp]+)\$";
219              
220             if ($]>=5.005) {
221             eval {
222             $re1= qr{$re1}o;
223             $re2= qr{$re2}o;
224             };
225             print_debug_class('e',"(util::before which) Error: $@") if $@;
226             }
227              
228             sub which
229             {
230 0     0 0   my $cmd= shift;
231 0           my $all= shift;
232 0 0         return undef unless $cmd;
233              
234              
235 0 0         if ($cmd =~ m|$re1|o ) {
236 0           $cmd =~ m|$re2|o;
237 0   0       my $path_element= $1 || '';
238 0   0       my $cmd_element= $2 || '';
239 0 0 0       return undef unless $path_element and $cmd_element;
240 0           $path_element=Psh::Util::abs_path($path_element);
241 0 0         return undef unless $path_element;
242 0           my $try= Psh::OS::catfile($path_element,$cmd_element);
243 0 0 0       if ((-x $try) and (! -d _)) { return $try; }
  0            
244 0           return undef;
245             }
246              
247 0 0 0       return $Psh::Util::command_hash{$cmd} if exists $Psh::Util::command_hash{$cmd} and !$all;
248              
249 0 0         if ($cmd !~ m/$Psh::which_regexp/) { return undef; }
  0            
250              
251 0 0         if ($last_path_cwd ne ($ENV{PATH} . $ENV{PWD})) {
252 0           $last_path_cwd = $ENV{PATH} . $ENV{PWD};
253              
254 0           recalc_absed_path();
255             }
256              
257 0           my @path_extension=Psh::OS::get_path_extension();
258 0           my @all=();
259              
260 0           foreach my $dir (@Psh::absed_path) {
261 0 0         next unless $dir;
262 0           my $try = Psh::OS::catfile($dir,$cmd);
263 0           foreach my $ext (@path_extension) {
264 0 0 0       if ((-x $try.$ext) and (!-d _)) {
265 0 0         $Psh::Util::command_hash{$cmd} = $try.$ext unless $all;
266 0 0         return $try.$ext unless $all;
267 0           push @all, $try.$ext;
268             }
269             }
270             }
271 0 0 0       if ($all and @all) {
272 0           return @all;
273             }
274 0           $Psh::Util::command_hash{$cmd} = undef; # no delete by purpose
275              
276 0           return undef;
277             }
278             }
279              
280             #
281             # starts_with( text, prefix)
282             # Returns true if text starts with prefix
283             #
284              
285             sub starts_with {
286 0     0 0   my ($text, $prefix) = @_;
287              
288 0   0       return length($text)>=length($prefix) &&
289             substr($text,0,length($prefix)) eq $prefix;
290             }
291              
292             #
293             # ends_with( text, suffix)
294             # Returns true if text ends with suffix
295             #
296              
297             sub ends_with {
298 0     0 0   my ( $text, $suffix) = @_;
299              
300 0   0       return length($text)>=length($suffix) &&
301             substr($text,-length($suffix)) eq $suffix;
302             }
303              
304             #
305             # list parse_hosts_file( text)
306             #
307             # Gets a standard hosts file as input and returns
308             # a list of the hostnames mentioned in the file
309             #
310             sub parse_hosts_file {
311 0     0 0   my $text= shift;
312 0           my @lines= split( /\n|\r|\r\n/, $text);
313 0           my @result= ();
314 0           foreach my $line (@lines) {
315 0 0         next if $line=~/^\s*$/; # Skip blank lines
316 0 0         next if $line=~/^\s*\#/; # Skip comment lines
317 0           $line=~/^\s*\S+\s(.*)$/;
318 0           my $rest= $1;
319 0           push @result, grep { length($_)>0 } split( /\s/, $rest);
  0            
320             }
321 0           return @result;
322             }
323              
324             #
325             # char prompt( string allowedchars, string prompt)
326             # prompts the user until he answers with one of the
327             # allowed characters
328             #
329             sub prompt {
330 0     0 0   my $allowed= shift;
331 0           $allowed= "^[$allowed]\$";
332 0           my $text= shift;
333 0           my $line='';
334              
335 0   0       do {
336 0           print $text;
337 0           $line=;
338             } while (!$line || lc($line) !~ $allowed);
339 0           chomp $line;
340 0           return lc($line);
341             }
342              
343              
344             1;
345              
346             __END__