| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package OptArgs2; |
|
2
|
6
|
|
|
6
|
|
576535
|
use strict; |
|
|
6
|
|
|
|
|
12
|
|
|
|
6
|
|
|
|
|
198
|
|
|
3
|
6
|
|
|
6
|
|
49
|
use warnings; |
|
|
6
|
|
|
|
|
10
|
|
|
|
6
|
|
|
|
|
271
|
|
|
4
|
6
|
|
|
6
|
|
3407
|
use Encode::Locale 'decode_argv'; |
|
|
6
|
|
|
|
|
143777
|
|
|
|
6
|
|
|
|
|
471
|
|
|
5
|
6
|
|
|
6
|
|
3290
|
use OptArgs2::Cmd; |
|
|
6
|
|
|
|
|
30
|
|
|
|
6
|
|
|
|
|
325
|
|
|
6
|
|
|
|
|
|
|
use Exporter::Tidy |
|
7
|
6
|
|
|
|
|
52
|
default => [qw/class_optargs cmd optargs subcmd arg opt/], |
|
8
|
6
|
|
|
6
|
|
8933
|
other => [qw/usage cols rows/]; |
|
|
6
|
|
|
|
|
98
|
|
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
our $VERSION = 'v2.0.17'; |
|
11
|
|
|
|
|
|
|
our @CARP_NOT = ( |
|
12
|
|
|
|
|
|
|
qw/ |
|
13
|
|
|
|
|
|
|
OptArgs2 |
|
14
|
|
|
|
|
|
|
OptArgs2::Arg |
|
15
|
|
|
|
|
|
|
OptArgs2::Cmd |
|
16
|
|
|
|
|
|
|
OptArgs2::CmdBase |
|
17
|
|
|
|
|
|
|
OptArgs2::Opt |
|
18
|
|
|
|
|
|
|
OptArgs2::OptArgBase |
|
19
|
|
|
|
|
|
|
OptArgs2::SubCmd |
|
20
|
|
|
|
|
|
|
/ |
|
21
|
|
|
|
|
|
|
); |
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
# constants |
|
24
|
|
|
|
|
|
|
sub USAGE_USAGE() { 'Usage' } # default |
|
25
|
|
|
|
|
|
|
sub USAGE_HELP() { 'Help' } |
|
26
|
|
|
|
|
|
|
sub USAGE_HELPTREE() { 'HelpTree' } |
|
27
|
|
|
|
|
|
|
sub USAGE_HELPSUMMARY() { 'HelpSummary' } |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
our $CURRENT; # legacy interface |
|
30
|
|
|
|
|
|
|
my %COMMAND; |
|
31
|
|
|
|
|
|
|
my @chars; |
|
32
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
sub _chars { |
|
34
|
0
|
0
|
|
0
|
|
0
|
if ( $^O eq 'MSWin32' ) { |
|
35
|
0
|
|
|
|
|
0
|
require Win32::Console; |
|
36
|
0
|
|
|
|
|
0
|
@chars = Win32::Console->new()->Size(); |
|
37
|
|
|
|
|
|
|
} |
|
38
|
|
|
|
|
|
|
else { |
|
39
|
0
|
|
|
|
|
0
|
require Term::Size::Perl; |
|
40
|
0
|
|
|
|
|
0
|
@chars = Term::Size::Perl::chars(); |
|
41
|
|
|
|
|
|
|
} |
|
42
|
0
|
|
|
|
|
0
|
\@chars; |
|
43
|
|
|
|
|
|
|
} |
|
44
|
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
sub cols { |
|
46
|
0
|
|
0
|
0
|
1
|
0
|
$chars[0] // _chars()->[0]; |
|
47
|
|
|
|
|
|
|
} |
|
48
|
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
sub rows { |
|
50
|
0
|
|
0
|
0
|
1
|
0
|
$chars[1] // _chars()->[1]; |
|
51
|
|
|
|
|
|
|
} |
|
52
|
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
sub die_paged { |
|
54
|
7
|
|
50
|
7
|
0
|
32
|
my $err = shift // 'die_paged($ERR)'; |
|
55
|
7
|
50
|
|
|
|
46
|
if ( -t STDERR ) { |
|
56
|
0
|
|
|
|
|
0
|
my $lines = scalar( split /\n/, $err ); |
|
57
|
0
|
0
|
|
|
|
0
|
$lines++ if $err =~ m/\n\z/; |
|
58
|
|
|
|
|
|
|
|
|
59
|
0
|
0
|
|
|
|
0
|
if ( $lines >= OptArgs2::rows() ) { |
|
60
|
0
|
|
|
|
|
0
|
require OptArgs2::Pager; |
|
61
|
0
|
|
|
|
|
0
|
my $pager = OptArgs2::Pager->new( auto => 0 ); |
|
62
|
0
|
|
|
|
|
0
|
local *STDERR = $pager->fh; |
|
63
|
0
|
|
|
|
|
0
|
die $err; |
|
64
|
|
|
|
|
|
|
} |
|
65
|
|
|
|
|
|
|
} |
|
66
|
|
|
|
|
|
|
|
|
67
|
7
|
|
|
|
|
95
|
die $err; |
|
68
|
|
|
|
|
|
|
} |
|
69
|
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
my %error_types = ( |
|
71
|
|
|
|
|
|
|
CmdExists => undef, |
|
72
|
|
|
|
|
|
|
CmdNotFound => undef, |
|
73
|
|
|
|
|
|
|
Conflict => undef, |
|
74
|
|
|
|
|
|
|
DuplicateAlias => undef, |
|
75
|
|
|
|
|
|
|
InvalidIsa => undef, |
|
76
|
|
|
|
|
|
|
ParentCmdNotFound => undef, |
|
77
|
|
|
|
|
|
|
SubCmdExists => undef, |
|
78
|
|
|
|
|
|
|
UndefOptArg => undef, |
|
79
|
|
|
|
|
|
|
Usage => undef, |
|
80
|
|
|
|
|
|
|
); |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
package OptArgs2::Status { |
|
83
|
|
|
|
|
|
|
use overload |
|
84
|
7
|
|
|
7
|
|
288
|
bool => sub { 1 }, |
|
85
|
0
|
|
|
0
|
|
0
|
'""' => sub { ${ $_[0] } }, |
|
|
0
|
|
|
|
|
0
|
|
|
86
|
6
|
|
|
6
|
|
3659
|
fallback => 1; |
|
|
6
|
|
|
|
|
12
|
|
|
|
6
|
|
|
|
|
76
|
|
|
87
|
|
|
|
|
|
|
} |
|
88
|
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
sub croak { |
|
90
|
2
|
|
|
2
|
0
|
19
|
require Carp; |
|
91
|
2
|
|
33
|
|
|
9
|
my $type = shift // Carp::croak( 'Usage', 'croak($TYPE, [$msg])' ); |
|
92
|
2
|
|
|
|
|
5
|
my $pkg = 'OptArgs2::Error::' . $type; |
|
93
|
2
|
|
33
|
|
|
7
|
my $msg = shift // "($pkg)"; |
|
94
|
2
|
50
|
|
|
|
7
|
$msg = sprintf( $msg, @_ ) if @_; |
|
95
|
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
Carp::croak( 'Usage', "unknown error type: $type" ) |
|
97
|
2
|
50
|
|
|
|
10
|
unless exists $error_types{$type}; |
|
98
|
|
|
|
|
|
|
|
|
99
|
2
|
|
|
|
|
759
|
$msg .= ' ' . Carp::longmess(''); |
|
100
|
|
|
|
|
|
|
|
|
101
|
6
|
|
|
6
|
|
1418
|
no strict 'refs'; |
|
|
6
|
|
|
|
|
15
|
|
|
|
6
|
|
|
|
|
4801
|
|
|
102
|
2
|
|
|
|
|
10
|
*{ $pkg . '::ISA' } = ['OptArgs2::Status']; |
|
|
2
|
|
|
|
|
41
|
|
|
103
|
|
|
|
|
|
|
|
|
104
|
2
|
|
|
|
|
15
|
die_paged( bless \$msg, $pkg ); |
|
105
|
|
|
|
|
|
|
} |
|
106
|
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
sub class_optargs { |
|
108
|
14
|
|
33
|
14
|
1
|
10089
|
my $class = shift |
|
109
|
|
|
|
|
|
|
|| croak( 'Usage', 'class_optargs($CMD,[@argv])' ); |
|
110
|
|
|
|
|
|
|
|
|
111
|
14
|
|
33
|
|
|
80
|
my $cmd = $COMMAND{$class} |
|
112
|
|
|
|
|
|
|
|| croak( 'CmdNotFound', 'command class not found: ' . $class ); |
|
113
|
|
|
|
|
|
|
|
|
114
|
14
|
|
|
|
|
37
|
my @source = @_; |
|
115
|
|
|
|
|
|
|
|
|
116
|
14
|
100
|
100
|
|
|
106
|
if ( !@_ and @ARGV ) { |
|
117
|
4
|
|
|
|
|
21
|
decode_argv(Encode::FB_CROAK); |
|
118
|
4
|
|
|
|
|
562
|
@source = @ARGV; |
|
119
|
|
|
|
|
|
|
} |
|
120
|
|
|
|
|
|
|
|
|
121
|
14
|
|
|
|
|
62
|
$cmd->parse(@source); |
|
122
|
|
|
|
|
|
|
} |
|
123
|
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
sub cmd { |
|
125
|
11
|
|
33
|
11
|
1
|
610915
|
my $class = shift || croak( 'Usage', 'cmd($CLASS,@args)' ); |
|
126
|
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
croak( 'CmdExists', "command already defined: $class" ) |
|
128
|
11
|
50
|
|
|
|
92
|
if exists $COMMAND{$class}; |
|
129
|
|
|
|
|
|
|
|
|
130
|
11
|
|
|
|
|
118
|
$COMMAND{$class} = OptArgs2::Cmd->new( class => $class, @_ ); |
|
131
|
|
|
|
|
|
|
} |
|
132
|
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
sub optargs { |
|
134
|
4
|
|
|
4
|
1
|
706987
|
my $class = caller; |
|
135
|
|
|
|
|
|
|
|
|
136
|
4
|
0
|
33
|
|
|
18
|
if ( !@_ and exists $COMMAND{$class} ) { # Legacy interface |
|
137
|
0
|
|
|
|
|
0
|
return ( class_optargs($class) )[1]; |
|
138
|
|
|
|
|
|
|
} |
|
139
|
|
|
|
|
|
|
|
|
140
|
4
|
|
|
|
|
31
|
delete $COMMAND{$class}; |
|
141
|
4
|
|
|
|
|
18
|
cmd( $class, @_ ); |
|
142
|
4
|
|
|
|
|
16
|
( class_optargs($class) )[1]; |
|
143
|
|
|
|
|
|
|
} |
|
144
|
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
sub subcmd { |
|
146
|
6
|
|
33
|
6
|
1
|
351821
|
my $class = shift || croak( 'Usage', 'subcmd($CLASS,%%args)' ); |
|
147
|
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
croak( 'SubCmdExists', "subcommand already defined: $class" ) |
|
149
|
6
|
50
|
|
|
|
19
|
if exists $COMMAND{$class}; |
|
150
|
|
|
|
|
|
|
|
|
151
|
6
|
100
|
|
|
|
55
|
croak( 'ParentCmdNotFound', |
|
152
|
|
|
|
|
|
|
"no '::' in class '$class' - must have a parent" ) |
|
153
|
|
|
|
|
|
|
unless $class =~ m/(.+)::(.+)/; |
|
154
|
|
|
|
|
|
|
|
|
155
|
5
|
|
|
|
|
19
|
my $parent_class = $1; |
|
156
|
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
croak( 'ParentCmdNotFound', "parent class not found: " . $parent_class ) |
|
158
|
5
|
50
|
|
|
|
23
|
unless exists $COMMAND{$parent_class}; |
|
159
|
|
|
|
|
|
|
|
|
160
|
5
|
|
|
|
|
27
|
$COMMAND{$class} = $COMMAND{$parent_class}->add_cmd( |
|
161
|
|
|
|
|
|
|
class => $class, |
|
162
|
|
|
|
|
|
|
@_ |
|
163
|
|
|
|
|
|
|
); |
|
164
|
|
|
|
|
|
|
} |
|
165
|
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
sub usage { |
|
167
|
0
|
|
0
|
0
|
1
|
|
my $class = shift || do { |
|
168
|
|
|
|
|
|
|
my ($pkg) = caller; |
|
169
|
|
|
|
|
|
|
$pkg; |
|
170
|
|
|
|
|
|
|
}; |
|
171
|
0
|
|
|
|
|
|
my $style = shift; |
|
172
|
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
croak( 'CmdNotFound', "command not found: $class" ) |
|
174
|
0
|
0
|
|
|
|
|
unless exists $COMMAND{$class}; |
|
175
|
|
|
|
|
|
|
|
|
176
|
0
|
|
|
|
|
|
return $COMMAND{$class}->usage_string($style); |
|
177
|
|
|
|
|
|
|
} |
|
178
|
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
# Legacy interface, no longer documented |
|
180
|
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
sub arg { |
|
182
|
0
|
|
|
0
|
1
|
|
my $name = shift; |
|
183
|
0
|
|
|
|
|
|
my $class = scalar caller; |
|
184
|
|
|
|
|
|
|
|
|
185
|
0
|
|
0
|
|
|
|
$OptArgs2::CURRENT //= cmd( $class, comment => '' ); |
|
186
|
0
|
|
|
|
|
|
$OptArgs2::CURRENT->add_arg( |
|
187
|
|
|
|
|
|
|
name => $name, |
|
188
|
|
|
|
|
|
|
@_, |
|
189
|
|
|
|
|
|
|
); |
|
190
|
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
} |
|
192
|
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
sub opt { |
|
194
|
0
|
|
|
0
|
1
|
|
my $name = shift; |
|
195
|
0
|
|
|
|
|
|
my $class = scalar caller; |
|
196
|
|
|
|
|
|
|
|
|
197
|
0
|
|
0
|
|
|
|
$OptArgs2::CURRENT //= cmd( $class, comment => '' ); |
|
198
|
0
|
|
|
|
|
|
$OptArgs2::CURRENT->add_opt( |
|
199
|
|
|
|
|
|
|
name => $name, |
|
200
|
|
|
|
|
|
|
@_, |
|
201
|
|
|
|
|
|
|
); |
|
202
|
|
|
|
|
|
|
} |
|
203
|
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
1; |
|
205
|
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
__END__ |