File Coverage

blib/lib/Term/Clui/FileSelect.pm
Criterion Covered Total %
statement 8 156 5.1
branch 0 108 0.0
condition 0 30 0.0
subroutine 3 4 75.0
pod 1 1 100.0
total 12 299 4.0


line stmt bran cond sub pod time code
1             # Term/Clui/FileSelect.pm
2             #########################################################################
3             # This Perl module is Copyright (c) 2002, Peter J Billam #
4             # c/o P J B Computing, www.pjb.com.au #
5             # #
6             # This module is free software; you can redistribute it and/or #
7             # modify it under the same terms as Perl itself. #
8             #########################################################################
9              
10             package Term::Clui::FileSelect;
11             our $VERSION = '1.74_01';
12             $VERSION =~ tr/_//d;
13             import Term::Clui(':DEFAULT','back_up');
14             require Exporter;
15             @ISA = qw(Exporter);
16             @EXPORT = qw(select_file);
17             @EXPORT_OK = qw();
18              
19 1     1   980 use 5.006;
  1         3  
20 1     1   4 no strict; no warnings;
  1     1   2  
  1         17  
  1         3  
  1         1  
  1         1362  
21              
22             my $home = $ENV{HOME} || $ENV{LOGDIR} || (getpwuid($>))[7];
23             $home =~ s#([^/])$#$1/#;
24              
25 0     0 1   sub select_file { my %option = @_;
26 0 0         if (!defined $option{'-Path'}) { $option{'-Path'}=$option{'-initialdir'}; }
  0            
27 0 0         if (!defined $option{'-FPat'}) { $option{'-FPat'}=$option{'-filter'}; }
  0            
28 0 0         if (!defined $option{'-ShowAll'}) {
29 0           $option{'-ShowAll'} = $option{'-dotfiles'};
30             }
31 0 0         if ($option{'-Directory'}) { $option{'-Chdir'}=1; $option{'-SelDir'}=1; }
  0            
  0            
32 0           my $multichoice = 0;
33 0 0 0       if (wantarray && !$option{'-Chdir'} && !$option{'-Create'}) {
    0 0        
34 0           $option{'-DisableShowAll'} = 1;
35 0           $multichoice = 1;
36             } elsif (!defined $option{'-Chdir'}) {
37 0           $option{'-Chdir'} = 1;
38             }
39              
40 0 0 0       if ($option{'-Path'} && -d $option{'-Path'}) {
41 0           $dir=$option{'-Path'};
42 0 0         if ($dir =~ m#[^/]$#) { $dir .= '/'; }
  0            
43             } else {
44 0           $dir = $home;
45             }
46 0 0         if ($option{'-TopDir'}) {
47 0 0         if (!-d $option{'-TopDir'}) { delete $option{'-TopDir'};
  0 0          
48 0           } elsif ($option{'-TopDir'} =~ m#[^/]$#) { $option{'-TopDir'} .= '/';
49             }
50 0 0         if (index $dir, $option{'-TopDir'}) { $dir = $option{'-TopDir'}; }
  0            
51             }
52              
53 0           my ($new, $file, @allfiles, @files, @dirs, @pre, @post, %seen, $isnew);
54 0           my @dotfiles;
55              
56 0           while () {
57 0 0         if (! opendir (D, $dir)) { warn "can't opendir $dir: $!\n"; return 0; }
  0            
  0            
58 0 0         if ($option{'-SelDir'}) { @pre = ('./'); } else { @pre = (); }
  0            
  0            
59 0           @post = ();
60 0           @allfiles = sort grep(!/^\.\.?$/, readdir D); closedir D;
  0            
61 0           @dotfiles = grep(/^\./, @allfiles);
62 0 0         if ($option{'-ShowAll'}) {
63 0 0 0       if (@dotfiles && !$option{'-DisableShowAll'}) {
64 0           @post='Hide DotFiles';
65             }
66             } else {
67 0           @allfiles = grep(!/^\./, @allfiles);
68 0 0 0       if (@dotfiles && !$option{'-DisableShowAll'}) {
69 0           @post='Show DotFiles';
70             }
71             }
72             # split @allfiles into @files and @dirs for option processing ...
73 0   0       @dirs = grep(-d "$dir/$_" && -r "$dir/$_", @allfiles);
74 0 0         if ($option{'-Directory'}) {
    0          
75 0           @files = ();
76             } elsif ($option{'-FPat'}) {
77 0           @files = grep(!-d $_, glob("$dir/$option{'-FPat'}"));
78 0           my $length = 1 + length $dir;
79 0           foreach (@files) { $_ = substr $_, $length; }
  0            
80             } else {
81 0           @files = grep(!-d "$dir/$_", @allfiles);
82             }
83 0 0         if ($option{'-Chdir'}) {
    0          
84 0           foreach (@dirs) { s#$#/#; }
  0            
85 0 0         if ($option{'-TopDir'}) {
86 0           my $up = $dir; $up =~ s#[^/]+/?$##; # find parent directory
  0            
87 0 0         if (-1 < index $up, $option{'-TopDir'}) { unshift @pre, '../'; }
  0            
88             # must check for symlinks to outside the TopDir ...
89 0           } else { unshift @pre, '../';
90             }
91             } elsif (!$option{'-SelDir'}) {
92 0           @dirs = ();
93             }
94 0 0         if ($option{'-Create'}) { unshift @post, 'Create New File'; }
  0            
95 0 0         if ($option{'-TextFile'}) { @files = grep(-T "$dir/$_", @files); }
  0            
96 0 0         if ($option{'-Owned'}) { @files = grep(-o "$dir/$_", @files); }
  0            
97 0 0         if ($option{'-Executable'}) { @files = grep(-x "$dir/$_", @files); }
  0            
98 0 0         if ($option{'-Writeable'}) { @files = grep(-w "$dir/$_", @files); }
  0            
99 0 0         if ($option{'-Readable'}) { @files = grep(-r "$dir/$_", @files); }
  0            
100 0           @allfiles = (@pre, (sort @dirs,@files), @post); # reconstitute @allfiles
101              
102 0           my $title;
103 0 0         if ($option{'-Title'}) { $title = "$option{'-Title'} in $dir"
  0            
104 0           } else { $title = "in directory $dir ?";
105             }
106 0 0         if ($option{'-File'}) { &set_default($title, $option{'-File'}) }
  0            
107 0           $Term::Clui::SpeakMode{'dot'} = 1;
108 0 0         if ($multichoice) {
109 0           my @new = &choose ($title, @allfiles);
110 0           $Term::Clui::SpeakMode{'dot'} = 0;
111 0 0         return () unless @new;
112 0           foreach (@new) { $_="$dir$_"; }
  0            
113 0           return @new;
114             }
115 0           $new = &choose ($title, @allfiles);
116 0           $Term::Clui::SpeakMode{'dot'} = 0;
117              
118 0 0 0       if ($option{'-ShowAll'} && $new eq 'Hide DotFiles') {
    0 0        
119 0           delete $option{'-ShowAll'}; redo;
  0            
120             } elsif (!$option{'-ShowAll'} && $new eq 'Show DotFiles') {
121 0           $option{'-ShowAll'} = 1; redo;
  0            
122             }
123 0 0         if ($new eq "Create New File") {
124 0           $new = &ask ("new file name ?"); # validating this is a chore ...
125 0 0         if (! $new) { next; }
  0            
126 0 0         if ($new =~ m#^/#) { $file = $new; } else { $file = "$dir$new"; }
  0            
  0            
127 0           $file =~ s#/+#/#g; # simplify //// down to /
128 0           while ($file =~ m#./\.\./#) { $file =~ s#[^/]*/\.\./##; } # zap /../
  0            
129 0           $file =~ s#/[^/]*/\.\.$##; # and /.. at end
130 0 0         if ($option{'-TopDir'}) { # check against escape from TopDir
131 0 0         if (index $file, $option{'-TopDir'}) {
132 0           $dir = $option{'-TopDir'}; next;
  0            
133             }
134             }
135 0 0         if (-d $file) { # pre-existing directory ?
136 0 0         if ($option{'-SelDir'}) { return $file;
  0            
137             } else {
138 0 0         $dir=$file; if ($dir =~ m#[^/]$#) { $dir.='/'; } next;
  0            
  0            
  0            
139             }
140             }
141 0           $file =~ m#^(.*/)([^/]+)$#;
142 0 0         if (-e $file) { $dir = $1; $option{'-File'} = $2; next; } # exists ?
  0            
  0            
  0            
143             # must check for creatability (e.g. dir exists and is writeable)
144 0 0 0       if (-d $1 && -w $1) { return $file; }
  0            
145 0 0         if (!-d $1) { &sorry ("directory $1 does not exist."); next; }
  0            
  0            
146 0           &sorry ("directory $1 is not writeable."); next;
  0            
147             }
148 0 0         return undef unless $new;
149 0 0 0       if ($new eq './' && $option{'-SelDir'}) { return $dir; }
  0            
150 0 0         if ($new =~ m#^/#) { $file = $new; # abs filename
  0            
151 0           } else { $file = "$dir$new"; # rel filename (slash always at end)
152             }
153 0 0         if ($new eq '../') { $dir =~ s#[^/]+/?$##; &back_up(); next;
  0 0          
  0 0          
  0 0          
154             } elsif ($new eq './') {
155 0 0         if ($option{'-SelDir'}) { return $dir; } $file = $dir;
  0            
  0            
156 0           } elsif ($file =~ m#/$#) { $dir = $file; &back_up(); next;
  0            
  0            
157 0           } elsif (-f $file) { return $file;
158             }
159             }
160             }
161             1;
162              
163             __END__