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 0 7 0.0
total 146 233 62.6


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, 2023 INABA Hitoshi
9             ######################################################################
10              
11             $VERSION = '0.14';
12             $VERSION = $VERSION;
13              
14 9     9   33722 use 5.00503;
  9         75  
15 9     9   51 use strict;
  9         20  
  9         371  
16 9 50   9   241 BEGIN { $INC{'warnings.pm'} = '' if $] < 5.006 }; use warnings; local $^W=1;
  9     9   49  
  9         16  
  9         418  
17              
18 9     9   54 use Fcntl;
  9         14  
  9         14341  
19              
20             #---------------------------------------------------------------------
21             sub Modern::Open::confess (@) {
22 22     22 0 108 my $i = 0;
23 22         44 my @confess = ();
24 22         166 while (my($package,$filename,$line,$subroutine) = caller($i)) {
25 66         204 push @confess, "[$i] $filename($line) $subroutine\n";
26 66         249 $i++;
27             }
28 22         161 print STDERR "\n", @_, "\n";
29 22         111 print STDERR CORE::reverse @confess;
30 22         135 die;
31             }
32              
33             #---------------------------------------------------------------------
34             sub Modern::Open::open (*$;$) {
35 34     34 0 7297 my $handle;
36              
37 34 100       91 if (defined $_[0]) {
38 17         31 Modern::Open::confess "Bare handle no longer supported";
39             }
40             else {
41 17         21 $handle = $_[0] = \do { local *_ };
  17         103  
42             }
43              
44 17 50       59 if (@_ >= 4) {
    100          
    50          
45 0         0 Modern::Open::confess "Too many arguments for open";
46             }
47             elsif (@_ == 3) {
48 8         27 my($mode,$filename) = @_[1,2];
49              
50 8 100       20 if ($mode eq '-|') {
    100          
51 1         1690 my $return = CORE::open($handle,qq{$filename |});
52 1 50 33     98 if ($return or defined wantarray) {
53 1         40 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         2069 my $return = CORE::open($handle,qq{| $filename});
61 1 50 33     45 if ($return or defined wantarray) {
62 1         39 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       14 if (not exists $flags{$mode}) {
78 0         0 Modern::Open::confess "Unknown open() mode '$mode'";
79             }
80 6         309 my $return = CORE::sysopen($handle,$filename,$flags{$mode});
81 6 50 33     33 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         4068 my $return = CORE::open($handle,$_[1]);
91 9 50 33     88 if ($return or defined wantarray) {
92 9         80 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 82 my $handle;
106              
107 2 100       7 if (defined $_[0]) {
108 1         5 Modern::Open::confess "Bare handle no longer supported";
109             }
110             else {
111 1         2 $handle = $_[0] = \do { local *_ };
  1         6  
112             }
113              
114 1         2 my $return;
115 1 50 0     39 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     8 if ($return or defined wantarray) {
122 1         5 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 79 my $handle;
132              
133 2 100       8 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         5  
138             }
139              
140 1 50       8 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         55 my $return = CORE::sysopen($handle,$_[1],$_[2]);
154 1 50 33     9 if ($return or defined wantarray) {
155 1         4 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 80 my($handle0,$handle1);
169              
170 2 100       8 if (defined $_[0]) {
171 1         3 Modern::Open::confess "Bare handle no longer supported";
172             }
173             else {
174 1         2 $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         2 $handle1 = $_[1] = \do { local *_ };
  1         3  
182             }
183              
184 1         37 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 1274 my $handle;
196              
197 3 100       14 if (defined $_[0]) {
198 2         8 Modern::Open::confess "Bare handle no longer supported";
199             }
200             else {
201 1         2 $handle = $_[0] = \do { local *_ };
  1         7  
202             }
203              
204             # socket doesn't autodie
205 1         101 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   80 no strict 'refs';
  9         18  
  9         1612  
237             {
238             # avoid: Prototype mismatch: sub main::open (*;$) vs (*$;$)
239 9     0   74 local $SIG{__WARN__} = sub {};
  9     9   61  
240 9         22 *{caller() . '::open'} = \&Modern::Open::open;
  9         83  
241             }
242 9         23 *{caller() . '::opendir'} = \&Modern::Open::opendir;
  9         36  
243 9         18 *{caller() . '::sysopen'} = \&Modern::Open::sysopen;
  9         36  
244 9         19 *{caller() . '::pipe'} = \&Modern::Open::pipe;
  9         60  
245 9         19 *{caller() . '::socket'} = \&Modern::Open::socket;
  9         31  
246 9         17 *{caller() . '::accept'} = \&Modern::Open::accept;
  9         9298  
247             }
248              
249             1;
250              
251             __END__