File Coverage

blib/lib/AppConfig/Getopt.pm
Criterion Covered Total %
statement 55 63 87.3
branch 18 24 75.0
condition 3 3 100.0
subroutine 9 10 90.0
pod 0 2 0.0
total 85 102 83.3


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