File Coverage

blib/lib/Zoidberg/Utils/FileSystem.pm
Criterion Covered Total %
statement 34 68 50.0
branch 8 28 28.5
condition 1 7 14.2
subroutine 7 11 63.6
pod 3 5 60.0
total 53 119 44.5


line stmt bran cond sub pod time code
1             package Zoidberg::Utils::FileSystem;
2              
3             our $VERSION = '0.981';
4              
5 18     18   3468 use strict;
  18         51  
  18         698  
6             #use File::Spec;
7 18     18   1935 use Env qw/@PATH/;
  18         4044  
  18         146  
8 18     18   2876 use File::Spec; # TODO make more use of this lib
  18         39  
  18         387  
9 18     18   18975 use Encode;
  18         553139  
  18         1971  
10             use Exporter::Tidy
11 18     18   182 default => [qw/path list_path list_dir unique_file regex_glob/];
  18         53  
  18         221  
12              
13             our $DEVNULL = File::Spec->devnull();
14              
15             sub path {
16             # return absolute path
17             # argument: string optional: reference
18 33   50 33 1 151 my $string = shift || return $ENV{PWD};
19 33 50       180 my $refer = $_[0] ? path(shift @_) : $ENV{PWD}; # possibly recurs
20 33         100 $refer =~ s/\/$//;
21 33         193 $string =~ s{/+}{/}; # ever tried using $::main::main::main::something ?
22 33 100       167 unless ($string =~ m{^/}) {
23 17 50       119 if ( $string =~ /^~([^\/]*)/ ) {
    50          
24 0 0       0 if ($1) {
25 0         0 my @info = getpwnam($1);
26             # @info = ($name, $passwd, $uid, $gid, $quota, $comment, $gcos, $dir, $shell).
27 0         0 $string =~ s{^~$1/?}{$info[7]/};
28             }
29 0         0 else { $string =~ s{^~/?}{$ENV{HOME}/}; }
30             }
31             elsif ( $string =~ s{^\.(\.+)(/|$)}{}) {
32 0         0 my $l = length($1);
33 0         0 $refer =~ s{(/[^/]*){0,$l}$}{};
34 0         0 $string = $refer.'/'.$string;
35             }
36             else {
37 17         104 $string =~ s{^\.(/|$)}{};
38 17         68 $string = $refer.'/'.$string;
39             }
40             }
41 33         96 $string =~ s/\\//g;
42 33         115 return $string;
43             }
44              
45             sub list_dir {
46 17 50   17 1 103 my $dir = @_ ? shift : $ENV{PWD};
47 17 50       135 $dir =~ s#/$## unless $dir eq '/';
48 17         68 $dir = path($dir);
49              
50 17 50       1370 opendir DIR, $dir or die "could not open dir: $dir";
51 17         229537 my @items = grep {$_ !~ /^\.{1,2}$/} readdir DIR ;
  126         364  
52 17         370 closedir DIR;
53              
54 17         112 @items = map Encode::decode_utf8($_, 1), @items;
55 17         2237 return @items;
56             }
57              
58 0     0 1   sub list_path { return map list_dir($_), grep {-d $_} @PATH }
  0            
59              
60             sub unique_file {
61 0   0 0 0   my $string = pop || "untitledXXXX";
62 0           my ($file, $number) = ($string, 0);
63 0           $file =~ s/XXXX/$number/;
64 0           while ( -e $file ) {
65 0 0         if ($number > 256) {
66 0           $file = undef;
67 0           last;
68             } # infinite loop protection
69             else {
70 0           $file = $string;
71 0           $file =~ s/XXXX/$number/;
72             }
73 0           $number++
74             };
75 0 0         die qq/could not find any non-existent file for string "$string"/
76             unless defined $file;
77 0           return $file;
78             }
79              
80             # [! => [^
81             # * => .*
82             # ? => .?
83             # leave [] {} ()
84             # quote other like $ @ % etc.
85              
86             #sub glob {
87             #
88             #}
89              
90             sub regex_glob {
91 0     0 0   my ($glob, $opt) = @_;
92 0           my @regex = $Zoidberg::CURRENT->{stringparser}->split(qr#/#, $glob);
93 0           return _regex_glob_recurs(\@regex, '.', $opt);
94             }
95              
96             sub _regex_glob_recurs {
97 0     0     my ($regexps, $dir, $opt) = @_;
98 0           my $regexp = shift @$regexps;
99 0 0         $regexp = "(?$opt:".$regexp.')' if $opt;
100             #debug "globbing for dir '$dir', regexp '$regexp', opt '$opt'\n";
101 0           opendir DIR, $dir;
102 0           my @matches = @$regexps
103 0 0 0       ? ( map { _regex_glob_recurs([@$regexps], $dir.'/'.$_, $opt) }
104 0 0         grep { -d $_ and $_ !~ /^\.{1,2}$/ and m/$regexp/ } readdir DIR )
105 0 0         : ( map "$dir/$_", grep { $_ !~ /^\.{1,2}$/ and m/$regexp/ } readdir DIR ) ;
106 0           closedir DIR;
107 0           return @matches;
108             }
109              
110             1;
111              
112             __END__