File Coverage

blib/lib/clobber.pm
Criterion Covered Total %
statement 62 73 84.9
branch 27 40 67.5
condition 19 31 61.2
subroutine 13 13 100.0
pod 0 3 0.0
total 121 160 75.6


line stmt bran cond sub pod time code
1             package clobber;
2 2     2   105921 use Carp;
  2         5  
  2         151  
3 2     2   11 use Fcntl;
  2         4  
  2         522  
4 2     2   11 use strict; no strict 'refs';
  2     2   6  
  2         71  
  2         10  
  2         3  
  2         53  
5 2     2   9 use vars '$VERSION'; $VERSION = 0.10_1;
  2         3  
  2         139  
6             eval "require Term::ReadKey";
7              
8 2   50 2   926 BEGIN{ $^I||="~" }
9              
10             sub unimport { #no strict 'refs';
11 2   50 2   27 my $opt = $_[1] || '';
12 2 50       20 $^H{'clobber-lax'} = $opt eq ':lax' ? 1 : 0;
13              
14 2 100       9 unless( exists($^H{clobber}) ){
15 1         5 *{"CORE::GLOBAL::\L$_"} = \&{$_} foreach qw/OPEN RENAME SYSOPEN/;
  3         21  
  3         17  
16             }
17 2   50     3148 $^H{'clobber'} = $ENV{'clobber.pm'} || 0;
18             }
19              
20             sub import {
21 2   100 2   32 my $opt = $_[1] || '';
22 2 100       8 if( $opt eq ':lax' ){
23 1         3 $^H{'clobber-lax'} = 1;
24 1         3 &unimport();
25             }
26             else{
27 1         13 $^H{'clobber'} = 1;
28             }
29             }
30              
31              
32             sub OPEN(*;$@){
33 11     11   91681 my($handle, $mode, $file) = @_;
34 11         31 my($testmode, $pipein) = $mode;
35 11         99 my $scope = (caller 0)[10];
36              
37 11 50       134 my $stricture = $scope->{'clobber-lax'} ?
38             qr/^\+>(?!>)|^>(?!&|>)/ : qr/^\+[<>](?!>)|^>(?!&|>)/;
39              
40 11 100       56 if( scalar(@_) == 1 ){ #no strict 'refs';
41 1         3 unshift(@_, $mode = ${caller(1).'::'.$handle});
  1         13  
42             }
43              
44 11 100       51 if( scalar(@_) == 2 ){
    50          
45             #Since we can't simply pass @_ through due to open's prototype,
46             #we might as well convert to 3-arg
47              
48 7 50       128 if( $mode =~ /^\s*
49             (
50             \| | #pipe-out
51             (?:\>{1,2}|<)&=?| #dup & fdopen
52             \+?>{1,2}| #write, append, write-read, append-read
53             \+?< #read, read-write
54             )?
55             \s*
56             (.+?) #the beef
57             \s*
58             (\|)? #pipe-in
59             \s*
60             $/x ){
61 7   100     125 ($testmode, $file, $pipein) = ($1||'', $2||'', $3||'');
      50        
      100        
62             #if it's a 2-arg dup and we're a stale perl, just do it & return;
63 2 100 66 2   3797 return CORE::open($handle, $mode) if $[ < 5.008 &&
  2         877  
  2         7705  
  7         229  
64             $mode =~ /^\s*(?:\>{1,2}|<)&=?/;
65             }
66             else{
67 0         0 croak "Failed to parse EXPR of 2-arg open: $_[1]";
68             }
69              
70 5 50       22 $testmode = $testmode eq '|' ? '|-' : $testmode;
71 5 100       17 unless( length $testmode ){
72 1 0       4 $testmode = $pipein ? '-|' :
    50          
73             $file eq '-' ? '<' : '>';
74             }
75             }
76             elsif( scalar(@_) > 2 ){
77 4         28 ($testmode, $file) = @_[1,2];
78             }
79              
80 9 100 100     561 prompt($file, $scope) if -e $file && $testmode =~ /$stricture/;
81              
82 2         8 splice(@_, 0, 3);
83              
84             #no strict 'refs';
85 2         3 CORE::open(*{caller(0) . '::' . $handle}, $testmode, $file, @_);
  2         4402  
86             }
87              
88             sub SYSOPEN(*$$;$){
89 5     5 0 2460 my($handle, $file, $mode, $perms) = @_;
90 5         27 my $scope = (caller 0)[10];
91              
92 5 50       29 my $stricture = $scope->{'clobber-lax'} ? O_TRUNC : (O_WRONLY|O_RDWR|O_TRUNC);
93              
94             #We don't use O_EXCL because sysopen's failure is not trappable
95 5 100 66     102 prompt($file, $scope) if -e $file && $mode&$stricture;
96              
97             #no strict 'refs';
98 1   50     3 CORE::sysopen(*{caller(0) . '::' . $handle}, $file, $mode, $perms||0666);
  1         155  
99             }
100              
101             sub RENAME($$){
102 1     1 0 460 my $scope = (caller 0)[10];
103              
104 1 50       30 prompt($_[1], $scope, "$_[0]: overwrite `$_[1]'?") if -e $_[1];
105              
106 0         0 CORE::rename($_[0], $_[1]);
107             }
108              
109             sub prompt{
110 12     12 0 22 my $clobber = 0;
111              
112 12 50       40 return if $_[1]->{'clobber'};
113              
114 12 50 33     42 if( -t STDIN && exists($INC{'Term/ReadKey.pm'}) ){
115              
116 0         0 select(STDERR); local $|=1;
  0         0  
117 0   0     0 print STDERR ($_[2] || "Allow modification of '$_[0]'?") . ' [yN] ';
118              
119 0         0 Term::ReadKey::ReadMode('cbreak'); $clobber = Term::ReadKey::ReadKey(0);
  0         0  
120              
121 0         0 Term::ReadKey::ReadMode('restore'); print STDERR "\n";
  0         0  
122              
123 0         0 $clobber =~ y/yY/1/; $clobber =~ y/1/0/c;
  0         0  
124             }
125              
126 12 50       2098 croak "$_[0]: File exists" unless $clobber;
127             }
128              
129              
130             1;
131             __END__