File Coverage

blib/lib/AppConfig/Getopt.pm
Criterion Covered Total %
statement 52 60 86.6
branch 18 24 75.0
condition 3 3 100.0
subroutine 8 9 88.8
pod 0 2 0.0
total 81 98 82.6


line stmt bran cond sub pod time code
1             #============================================================================
2             #
3             # AppConfig::Getopt.pm
4             #
5             # Perl5 module to interface AppConfig::* to Johan Vromans' Getopt::Long
6             # module. Getopt::Long implements the POSIX standard for command line
7             # options, with GNU extensions, and also traditional one-letter options.
8             # AppConfig::Getopt constructs the necessary Getopt:::Long configuration
9             # from the internal AppConfig::State and delegates the parsing of command
10             # line arguments to it. Internal variable values are updated by callback
11             # from GetOptions().
12             #
13             # Written by Andy Wardley
14             #
15             # Copyright (C) 1997-2007 Andy Wardley. All Rights Reserved.
16             # Copyright (C) 1997,1998 Canon Research Centre Europe Ltd.
17             #
18             #============================================================================
19              
20             package AppConfig::Getopt;
21 2     2   511 use strict;
  2         3  
  2         84  
22 2     2   7 use warnings;
  2         445  
  2         73  
23 2     2   8 use AppConfig::State;
  2         2  
  2         42  
24 2     2   1763 use Getopt::Long 2.17;
  2         25366  
  2         60  
25             our $VERSION = '1.69';
26              
27              
28             #------------------------------------------------------------------------
29             # new($state, \@args)
30             #
31             # Module constructor. The first, mandatory parameter should be a
32             # reference to an AppConfig::State object to which all actions should
33             # be applied. The second parameter may be a reference to a list of
34             # command line arguments. This list reference is passed to parse() for
35             # processing.
36             #
37             # Returns a reference to a newly created AppConfig::Getopt object.
38             #------------------------------------------------------------------------
39              
40             sub new {
41 2     2 0 5 my $class = shift;
42 2         4 my $state = shift;
43 2         5 my $self = {
44             STATE => $state,
45             };
46              
47 2         5 bless $self, $class;
48              
49             # call parse() to parse any arg list passed
50 2 50       8 $self->parse(@_)
51             if @_;
52              
53 2         22 return $self;
54             }
55              
56              
57             #------------------------------------------------------------------------
58             # parse(@$config, \@args)
59             #
60             # Constructs the appropriate configuration information and then delegates
61             # the task of processing command line options to Getopt::Long.
62             #
63             # Returns 1 on success or 0 if one or more warnings were raised.
64             #------------------------------------------------------------------------
65              
66             sub parse {
67 4     4 0 6 my $self = shift;
68 4         11 my $state = $self->{ STATE };
69 4         4 my (@config, $args, $getopt);
70              
71 4         7 local $" = ', ';
72              
73             # we trap $SIG{__WARN__} errors and patch them into AppConfig::State
74             local $SIG{__WARN__} = sub {
75 0     0   0 my $msg = shift;
76              
77             # AppConfig::State doesn't expect CR terminated error messages
78             # and it uses printf, so we protect any embedded '%' chars
79 0         0 chomp($msg);
80 0         0 $state->_error("%s", $msg);
81 4         32 };
82              
83             # slurp all config items into @config
84 4   100     67 push(@config, shift) while defined $_[0] && ! ref($_[0]);
85              
86             # add debug status if appropriate (hmm...can't decide about this)
87             # push(@config, 'debug') if $state->_debug();
88              
89             # next parameter may be a reference to a list of args
90 4         6 $args = shift;
91              
92             # copy any args explicitly specified into @ARGV
93 4 100       23 @ARGV = @$args if defined $args;
94              
95             # we enclose in an eval block because constructor may die()
96 4         6 eval {
97             # configure Getopt::Long
98 4         14 Getopt::Long::Configure(@config);
99              
100             # construct options list from AppConfig::State variables
101 4         145 my @opts = $self->{ STATE }->_getopt_state();
102              
103             # DEBUG
104 4 50       21 if ($state->_debug()) {
105 0         0 print STDERR "Calling GetOptions(@opts)\n";
106 0         0 print STDERR "\@ARGV = (@ARGV)\n";
107             };
108              
109             # call GetOptions() with specifications constructed from the state
110 4         12 $getopt = GetOptions(@opts);
111             };
112 4 50       210 if ($@) {
113 0         0 chomp($@);
114 0         0 $state->_error("%s", $@);
115 0         0 return 0;
116             }
117              
118             # udpdate any args reference passed to include only that which is left
119             # in @ARGV
120 4 100       17 @$args = @ARGV if defined $args;
121              
122 4         41 return $getopt;
123             }
124              
125              
126             #========================================================================
127             # AppConfig::State
128             #========================================================================
129              
130             package AppConfig::State;
131              
132             #------------------------------------------------------------------------
133             # _getopt_state()
134             #
135             # Constructs option specs in the Getopt::Long format for each variable
136             # definition.
137             #
138             # Returns a list of specification strings.
139             #------------------------------------------------------------------------
140              
141             sub _getopt_state {
142 4     4   5 my $self = shift;
143 4         5 my ($var, $spec, $args, $argcount, @specs);
144              
145 4     16   12 my $linkage = sub { $self->set(@_) };
  16         3345  
146              
147 4         5 foreach $var (keys %{ $self->{ VARIABLE } }) {
  4         25  
148 18 100       20 $spec = join('|', $var, @{ $self->{ ALIASES }->{ $var } || [ ] });
  18         63  
149              
150             # an ARGS value is used, if specified
151 18 100       46 unless (defined ($args = $self->{ ARGS }->{ $var })) {
152             # otherwise, construct a basic one from ARGCOUNT
153             ARGCOUNT: {
154 8         8 last ARGCOUNT unless
155 8 50       22 defined ($argcount = $self->{ ARGCOUNT }->{ $var });
156              
157 8 100       24 $args = "=s", last ARGCOUNT if $argcount eq ARGCOUNT_ONE;
158 4 100       26 $args = "=s@", last ARGCOUNT if $argcount eq ARGCOUNT_LIST;
159 2 50       5 $args = "=s%", last ARGCOUNT if $argcount eq ARGCOUNT_HASH;
160 2         3 $args = "!";
161             }
162             }
163 18 50       29 $spec .= $args if defined $args;
164              
165 18         28 push(@specs, $spec, $linkage);
166             }
167              
168 4         20 return @specs;
169             }
170              
171              
172              
173             1;
174              
175             __END__