File Coverage

lib/Modern/Open.pm
Criterion Covered Total %
statement 94 123 76.4
branch 32 58 55.1
condition 7 30 23.3
subroutine 13 15 86.6
pod 1 7 14.2
total 147 233 63.0


line stmt bran cond sub pod time code
1             package Modern::Open;
2             ######################################################################
3             #
4             # Modern::Open - Autovivification, Autodie, and 3-args open support
5             #
6             # https://metacpan.org/release/Modern-Open
7             #
8             # Copyright (c) 2014, 2015, 2018, 2019, 2020, 2021 INABA Hitoshi
9             ######################################################################
10              
11             $VERSION = '0.13';
12             $VERSION = $VERSION;
13              
14 9     9   37475 use 5.00503;
  9         92  
15 9     9   40 use strict;
  9         16  
  9         391  
16 9 50   9   176 BEGIN { $INC{'warnings.pm'} = '' if $] < 5.006 }; use warnings; local $^W=1;
  9     9   46  
  9         20  
  9         414  
17              
18 9     9   52 use Fcntl;
  9         15  
  9         13890  
19              
20             #---------------------------------------------------------------------
21             sub Modern::Open::confess (@) {
22 22     22 0 116 my $i = 0;
23 22         39 my @confess = ();
24 22         162 while (my($package,$filename,$line,$subroutine) = caller($i)) {
25 66         176 push @confess, "[$i] $filename($line) $subroutine\n";
26 66         235 $i++;
27             }
28 22         154 print STDERR "\n", @_, "\n";
29 22         100 print STDERR CORE::reverse @confess;
30 22         116 die;
31             }
32              
33             #---------------------------------------------------------------------
34             sub Modern::Open::open (*$;$) {
35 34     34 1 18953 my $handle;
36              
37 34 100       95 if (defined $_[0]) {
38 17         28 Modern::Open::confess "Bare handle no longer supported";
39             }
40             else {
41 17         21 $handle = $_[0] = \do { local *_ };
  17         116  
42             }
43              
44 17 50       63 if (@_ >= 4) {
    100          
    50          
45 0         0 Modern::Open::confess "Too many arguments for open";
46             }
47             elsif (@_ == 3) {
48 8         28 my($mode,$filename) = @_[1,2];
49              
50 8 100       27 if ($mode eq '-|') {
    100          
51 1         6152 my $return = CORE::open($handle,qq{$filename |});
52 1 50 33     90 if ($return or defined wantarray) {
53 1         53 return $return;
54             }
55             else {
56 0         0 Modern::Open::confess "Can't open($_[0],$_[1],$_[2]): $!";
57             }
58             }
59             elsif ($mode eq '|-') {
60 1         5328 my $return = CORE::open($handle,qq{| $filename});
61 1 50 33     68 if ($return or defined wantarray) {
62 1         44 return $return;
63             }
64             else {
65 0         0 Modern::Open::confess "Can't open($_[0],$_[1],$_[2]): $!";
66             }
67             }
68             else {
69 6         22 my %flags = (
70             '<' => O_RDONLY,
71             '>' => O_WRONLY | O_TRUNC | O_CREAT,
72             '>>' => O_WRONLY |O_APPEND | O_CREAT,
73             '+<' => O_RDWR,
74             '+>' => O_RDWR | O_TRUNC | O_CREAT,
75             '+>>' => O_RDWR | O_APPEND | O_CREAT,
76             );
77 6 50       18 if (not exists $flags{$mode}) {
78 0         0 Modern::Open::confess "Unknown open() mode '$mode'";
79             }
80 6         263 my $return = CORE::sysopen($handle,$filename,$flags{$mode});
81 6 50 33     37 if ($return or defined wantarray) {
82 6         32 return $return;
83             }
84             else {
85 0         0 Modern::Open::confess "Can't open($_[0],$_[1],$_[2]): $!";
86             }
87             }
88             }
89             elsif (@_ == 2) {
90 9         7483 my $return = CORE::open($handle,$_[1]);
91 9 50 33     106 if ($return or defined wantarray) {
92 9         172 return $return;
93             }
94             else {
95 0         0 Modern::Open::confess "Can't open($_[0],$_[1]): $!";
96             }
97             }
98             else {
99 0         0 Modern::Open::confess "Not enough arguments for open";
100             }
101             }
102              
103             #---------------------------------------------------------------------
104             sub Modern::Open::opendir (*$) {
105 2     2 0 66 my $handle;
106              
107 2 100       6 if (defined $_[0]) {
108 1         3 Modern::Open::confess "Bare handle no longer supported";
109             }
110             else {
111 1         2 $handle = $_[0] = \do { local *_ };
  1         5  
112             }
113              
114 1         2 my $return;
115 1 50 0     33 if ($return = CORE::opendir($handle,$_[1])) {
    0          
116             }
117             elsif (($^O =~ /MSWin32/) and (-d qq{$_[1].})) {
118 0         0 $return = CORE::opendir($handle,qq{$_[1].});
119             }
120              
121 1 50 33     6 if ($return or defined wantarray) {
122 1         4 return $return;
123             }
124             else {
125 0         0 Modern::Open::confess "Can't opendir($_[0],$_[1]): $!";
126             }
127             }
128              
129             #---------------------------------------------------------------------
130             sub Modern::Open::sysopen (*$$;$) {
131 2     2 0 100 my $handle;
132              
133 2 100       9 if (defined $_[0]) {
134 1         3 Modern::Open::confess "Bare handle no longer supported";
135             }
136             else {
137 1         2 $handle = $_[0] = \do { local *_ };
  1         6  
138             }
139              
140 1 50       7 if (@_ >= 5) {
    50          
    50          
141 0         0 Modern::Open::confess "Too many arguments for sysopen";
142             }
143             elsif (@_ == 4) {
144 0         0 my $return = CORE::sysopen($handle,$_[1],$_[2],$_[3]);
145 0 0 0     0 if ($return or defined wantarray) {
146 0         0 return $return;
147             }
148             else {
149 0         0 Modern::Open::confess "Can't sysopen($_[0],$_[1],$_[2],$_[3]): $!";
150             }
151             }
152             elsif (@_ == 3) {
153 1         57 my $return = CORE::sysopen($handle,$_[1],$_[2]);
154 1 50 33     8 if ($return or defined wantarray) {
155 1         5 return $return;
156             }
157             else {
158 0         0 Modern::Open::confess "Can't sysopen($_[0],$_[1],$_[2]): $!";
159             }
160             }
161             else {
162 0         0 Modern::Open::confess "Not enough arguments for sysopen";
163             }
164             }
165              
166             #---------------------------------------------------------------------
167             sub Modern::Open::pipe (**) {
168 2     2 0 81 my($handle0,$handle1);
169              
170 2 100       7 if (defined $_[0]) {
171 1         4 Modern::Open::confess "Bare handle no longer supported";
172             }
173             else {
174 1         1 $handle0 = $_[0] = \do { local *_ };
  1         6  
175             }
176              
177 1 50       3 if (defined $_[1]) {
178 0         0 Modern::Open::confess "Bare handle no longer supported";
179             }
180             else {
181 1         3 $handle1 = $_[1] = \do { local *_ };
  1         3  
182             }
183              
184 1         32 my $return = CORE::pipe($handle0,$handle1);
185 1 50 33     7 if ($return or defined wantarray) {
186 1         4 return $return;
187             }
188             else {
189 0         0 Modern::Open::confess "Can't pipe($_[0],$_[1]): $!";
190             }
191             }
192              
193             #---------------------------------------------------------------------
194             sub Modern::Open::socket (*$$$) {
195 3     3 0 1291 my $handle;
196              
197 3 100       12 if (defined $_[0]) {
198 2         7 Modern::Open::confess "Bare handle no longer supported";
199             }
200             else {
201 1         2 $handle = $_[0] = \do { local *_ };
  1         6  
202             }
203              
204             # socket doesn't autodie
205 1         63 return CORE::socket($handle,$_[1],$_[2],$_[3]);
206             }
207              
208             #---------------------------------------------------------------------
209             sub Modern::Open::accept (**) {
210 0     0 0 0 my($handle0,$handle1);
211              
212 0 0       0 if (defined $_[0]) {
213 0         0 Modern::Open::confess "Bare handle no longer supported";
214             }
215             else {
216 0         0 $handle0 = $_[0] = \do { local *_ };
  0         0  
217             }
218              
219 0 0       0 if (defined $_[1]) {
220 0         0 Modern::Open::confess "Bare handle no longer supported";
221             }
222              
223 0         0 my $return = CORE::accept($handle0,$handle1);
224 0 0 0     0 if ($return or defined wantarray) {
225 0         0 return $return;
226             }
227             else {
228 0         0 Modern::Open::confess "Can't accept($_[0],$_[1]): $!";
229             }
230             }
231              
232             #---------------------------------------------------------------------
233             sub import {
234              
235             # avoid: Can't use string ("main::open") as a symbol ref while "strict refs" in use
236 9     9   99 no strict 'refs';
  9         22  
  9         1621  
237             {
238             # avoid: Prototype mismatch: sub main::open (*;$) vs (*$;$)
239 9     0   73 local $SIG{__WARN__} = sub {};
  9     9   59  
240 9         22 *{caller() . '::open'} = \&Modern::Open::open;
  9         79  
241             }
242 9         19 *{caller() . '::opendir'} = \&Modern::Open::opendir;
  9         32  
243 9         35 *{caller() . '::sysopen'} = \&Modern::Open::sysopen;
  9         37  
244 9         19 *{caller() . '::pipe'} = \&Modern::Open::pipe;
  9         105  
245 9         25 *{caller() . '::socket'} = \&Modern::Open::socket;
  9         35  
246 9         19 *{caller() . '::accept'} = \&Modern::Open::accept;
  9         9784  
247             }
248              
249             1;
250              
251             __END__