File Coverage

blib/lib/Getopt/Yagow.pm
Criterion Covered Total %
statement 80 127 62.9
branch 33 44 75.0
condition 8 15 53.3
subroutine 9 17 52.9
pod 9 13 69.2
total 139 216 64.3


line stmt bran cond sub pod time code
1             package Getopt::Yagow;
2             # -*-Perl-*-
3             #
4             # DESCRIPTION
5             # Loads and parses command line options. See pod doc.
6             #
7             # AUTHOR AND COPYRIGHT
8             # Enrique Castilla Contreras
9             # Copyright (C) 2004-2007 Enrique Castilla.
10             #
11             #-----------------------------------------------------------------------
12             # $Id: Yagow.pm,v 1.1 2004/02/10 12:58:02 ecastilla Exp $
13             #-----------------------------------------------------------------------
14            
15 4     4   3382 use strict;
  4         9  
  4         160  
16 4     4   23 use vars qw( $VERSION );
  4         6  
  4         345  
17            
18             $VERSION = sprintf("%d.%02d", q$Revision: 1.1 $ =~ /(\d+)\.(\d+)/);
19            
20 4     4   5464 use Getopt::Long;
  4         101655  
  4         27  
21 4     4   7068 use Pod::Usage;
  4         347241  
  4         7128  
22            
23             # Usage: same as load_options.
24             #
25             sub new
26             {
27 8     8 1 5025 my $class = shift;
28            
29 8         25 my $this = bless {}, $class;
30 8         37 $this->load_options( @_ );
31            
32 8         23 return $this;
33             }
34            
35             # Usage:
36             # $opt = Getopt::Yagow->load_options; or
37             # $opt = Getopt::Yagow->load_options( 'option_spec' => default_value, ...) or
38             # $opt = Getopt::Yagow->load_options( { 'option_spec' => default_value, ... } ) or
39             # $opt = Getopt::Yagow->load_options( { ... }, ['pass_through', ... ] );
40             #
41             # Sample:
42             #
43             # $p->load_options(
44             # 'config=s' => '',
45             # 'srcdir:s' => '',
46             # 'tardir:s' => '',
47             # # 'help' => '', # Se aņade por defecto.
48             # 'css:s' => 'style.css',
49             # 'file_icon|f_icon:s' => 'c:\Perl\site\lib\tk\file.xbm',
50             # 'dir_icon|d_icon:s' => 'c:\Perl\site\lib\tk\folder.xbm'
51             # );
52             #
53             sub load_options
54             {
55 12     12 1 28 my $this = shift;
56            
57 12         19 my( $options_spec, $config);
58 12 100 66     136 if( @_ == 2 && ref $_[0] eq 'HASH' && ref $_[1] eq 'ARRAY' )
    100 66        
    100 66        
59             {
60 2         5 $options_spec = $_[0];
61 2         3 $config = $_[1];
62             }
63             elsif( @_ == 1 && ref $_[0] eq 'HASH' )
64             {
65 3         8 $options_spec = $_[0];
66             }
67             elsif( @_ >= 1 )
68             {
69             # Hash
70 1 50       6 $options_spec = { @_ } if @_ ;
71             }
72            
73 12 100       30 if( defined $config )
74             {
75 2         5 $this->{configuration} = $config;
76 2         7 Getopt::Long::Configure( @$config );
77             }
78            
79 12 100       113 return $this if ! defined $options_spec;
80            
81 6         28 while( my ($opt_spec,$default) = each %$options_spec )
82             {
83 32         73 $this->add_option( $opt_spec,$default );
84             }
85            
86 6         12 return $this;
87             }
88            
89             sub add_option
90             {
91 32     32 0 39 my ($this, $opt_spec, $default) = @_;
92            
93 32         97 (my $opt_name = $opt_spec) =~ s/([|=:!+]).*//;
94             # croak "Can't add_option '$opt_name', already defined"
95             # if exists $this->{$opt_name};
96            
97 32         86 $this->{options}->{$opt_name} = $opt_spec;
98            
99 32 100       86 $this->{default}->{$opt_name} = $default if defined $default;
100 32 100       117 if( ! defined $default )
101             {
102 6 50       24 $this->{mandatory} = [] if ! exists $this->{mandatory};
103 6         10 push @{$this->{mandatory}}, $opt_name ;
  6         32  
104             }
105             }
106            
107             sub usage
108             {
109 36     36 0 69 my $this = shift;
110 36         56 my $usage_opts = shift;
111            
112 36         136 pod2usage( $usage_opts );
113             }
114            
115             # Usage:
116             # $opt->parse_cmd_line( '--opt1 val1', '--opt2 val2', ... );
117             # $opt->parse_cmd_line( ... , '--optx valx',
118             # { -msg=>$msg_help,-verbose=>1 },
119             # { -msg=>$msg_wrong_syntax,-verbose=>0 } );
120             # $opt->parse_cmd_line( ... , '--optx valx',
121             # { -msg=>$msg_help,-verbose=>1 } );
122             # $opt->parse_cmd_line( ... , '--optx valx',
123             # undef,
124             # { -msg=>$msg_wrong_syntax,-verbose=>0 } );
125             #
126             sub parse_cmd_line
127             {
128 28     28 1 41831 my $this = shift;
129            
130 28         63 my $default_msg = "!! Incorrect syntax. Use --h for help !!.\n";
131            
132 28         42 my ($i,$arg,$help_usage,$wrong_syntax);
133            
134             # Cases:
135             # 1.- ... , {...}, {...}
136             # 3.- ... , undef, undef
137             # 4.- ... , {...}, undef
138             # 5.- ... , undef, {...}
139             # 6.- ... , undef
140             # 7.- ... , {...}
141             # 2.- {...}, {...}
142             # 8.- undef, undef
143             # 9.- undef, {...}
144             # 10.- {...}, undef
145             # 11.- {...}
146             # 12.- undef
147             #
148 28         49 my $hash_no = 1;
149 28         128 for( $i = 0; $i < @_; $i++ )
150             {
151 56         91 $arg = $_[$i];
152 56 50 33     407 if( (defined $arg && ref $arg eq 'HASH') || !defined $arg )
      33        
153             {
154 56 100       149 if( $hash_no == 1 )
155             {
156 28 50       77 $help_usage = $arg if defined $arg;
157 28         49 $hash_no = 2;
158             }
159            
160 56 100       134 if( $hash_no == 2 )
161             {
162 28 50       63 $wrong_syntax = $arg if defined $arg;
163 28         49 $hash_no = 3;
164             }
165            
166 56         99 splice @_,$i,1; # Supress $arg from argument list.
167 56         136 $i--;
168             }
169             }
170            
171 28 50       78 $wrong_syntax = {-msg=>$default_msg,-verbose=>0} if ! defined $wrong_syntax;
172 28 50       75 $help_usage = { -verbose => 1 } if ! defined $help_usage;
173            
174 28 50       131 my @args = @_ ? @_ : @ARGV;
175 28         82 local (@ARGV) = @args;
176            
177             #
178             # Handle command line parameters
179             #
180 28         36 my @options = values %{ $this->{options} };
  28         118  
181 28         57 my %used = ();
182 28 100       175 unless( GetOptions(\%used, 'help|h|?!', @options))
183             {
184 15         9097 $this->usage( $wrong_syntax );
185             }
186            
187 28 100       128184 if( exists $used{help} )
188             {
189 9         28 $this->usage( $help_usage );
190             }
191            
192             # If execution reaches this, syntax is correct from the point of view of
193             # GetOptions, but we require that options with 'undef' default value be
194             # specified in command line.
195             #
196 28         65316 foreach my $mandatory_opt ( @{$this->{mandatory}} )
  28         124  
197             {
198 19 100       80 if( ! exists $used{$mandatory_opt} )
199             {
200 12         159 warn "There is/are mandatory argument(s)";
201 12         86 $this->usage( $wrong_syntax );
202             }
203             }
204             # Also, options with default values, but used in command line, must be
205             # deleted.
206 28         124088 foreach ( keys %{$this->{default}} )
  28         203  
207             {
208 19 50       100 delete $this->{default}->{$_} if exists $used{$_};
209             }
210 28         94 $this->{used} = \%used;
211            
212             # Debug:
213             # print "# Getopt::Yagow. \@ARGV: ",join(',',@ARGV),"\n";
214            
215 28         86 $this->{unhandled_options} = [];
216 28         51 push @{$this->{unhandled_options}}, @ARGV;
  28         77  
217            
218 28         195 return $this;
219             }
220            
221             sub get_configuration
222             {
223 0     0 1   my $this = shift;
224            
225 0 0         return ( exists $this->{configuration} ? $this->{configuration} : [] );
226             }
227            
228             sub get_options
229             {
230 0     0 0   my $this = shift;
231            
232 0           return $this->{options};
233             }
234            
235             sub get_default
236             {
237 0     0 1   my $this = shift;
238            
239 0           return $this->{default};
240             }
241            
242             sub get_mandatory
243             {
244 0     0 1   my $this = shift;
245            
246 0           return $this->{mandatory};
247             }
248            
249             sub get_used
250             {
251 0     0 1   my $this = shift;
252            
253 0           return $this->{used};
254             }
255            
256             sub get_unhandled
257             {
258 0     0 1   my $this = shift;
259            
260 0           return $this->{unhandled_options};
261             }
262            
263             sub get_options_values
264             {
265 0     0 1   my $this = shift;
266            
267 0           return { %{$this->{default}}, %{$this->{used}} };
  0            
  0            
268             }
269            
270             sub DEBUG
271             {
272 0     0 0   my $this = shift;
273            
274 0           print STDERR "configuration:\n";
275 0           foreach my $key ( @{$this->{configuration}} )
  0            
276             {
277 0           print STDERR "$key\n";
278             }
279 0           print STDERR "\n";
280            
281 0           print STDERR "options:\n";
282 0           while( my($key,$val) = each %{$this->{options}} )
  0            
283             {
284 0           print STDERR "$key => $val\n";
285             }
286 0           print STDERR "\n";
287            
288 0           print STDERR "default:\n";
289 0           while( my($key,$val) = each %{$this->{default}} )
  0            
290             {
291 0           print STDERR "$key => $val\n";
292             }
293 0           print STDERR "\n";
294            
295 0           print STDERR "mandatory:\n";
296 0           foreach my $key ( @{$this->{mandatory}} )
  0            
297             {
298 0           print STDERR "$key\n";
299             }
300 0           print STDERR "\n";
301            
302 0           print STDERR "used:\n";
303 0           while( my($key,$val) = each %{$this->{used}} )
  0            
304             {
305 0           print STDERR "$key => $val\n";
306             }
307 0           print STDERR "\n";
308            
309 0           print STDERR "unhandled:\n";
310 0           foreach my $key ( @{$this->{unhandled_options}} )
  0            
311             {
312 0           print STDERR "$key\n";
313             }
314 0           print STDERR "\n";
315            
316             }
317            
318             __END__