File Coverage

blib/lib/Getopt/OO.pm
Criterion Covered Total %
statement 265 292 90.7
branch 201 232 86.6
condition 91 109 83.4
subroutine 15 15 100.0
pod 4 9 44.4
total 576 657 87.6


line stmt bran cond sub pod time code
1             #!/usr/local/bin/perl -w
2             # $Log: OO.pm,v $
3             # Revision 1.2 2005/07/30 01:25:16 builder
4             # fix to display bad key when values called with invalid key.
5             #
6             # Revision 1.13 2005/02/05 17:20:34 sjs
7             # Changed other_options to use required.
8             # Fixed checks for n_values in other_options.
9             #
10             # Revision 1.12 2005/02/03 03:41:13 sjs
11             # Fixed a couple of minor errors in other_values Values return.
12             # Rewrote the part of the Values method that decides what
13             # type to return to simplify debugging.
14             #
15             # Revision 1.11 2005/01/31 04:02:43 sjs
16             # - Fixed a problem with indent.
17             # - Fixed a problem with Getopt and mulit-value.
18             # - Added ability of other_values to use callback and ClientData.
19             # - Added several tests.
20             # - Modified error message for callback so that name of option
21             # generating error is displayed.
22             # - This should be it for feature modifications.
23             #
24             # Revision 1.10 2005/01/28 07:47:40 sjs
25             # modified other_values behaviour
26             #
27             # Revision 1.9 2005/01/27 15:38:02 sjs
28             # Change the way indent works on help. We now make string one char
29             # longer than option so help will be a little narrower rather than
30             # using a tab stop of 4.
31             #
32             # Revision 1.8 2005/01/27 15:35:34 sjs
33             # Change version to 0.05.
34             # Fix problem with indent.
35             #
36             # Revision 1.7 2005/01/23 21:38:45 sjs
37             # Fixed some problems with the pod and pod2man on older versions.
38             #
39             # Revision 1.6 2005/01/23 20:59:31 sjs
40             # Fixed a problem with multi_value not catching end of arguments
41             # correctly if option was not a '-'.
42             #
43             # Revision 1.5 2005/01/23 20:34:04 sjs
44             # - Renamed the other_args to be other_values to make things
45             # more consistent.
46             # - other_values no takes a number instead of a string and can
47             # be used to help the parser know how many arguments are expected
48             # after all the options have been parsed.
49             # - Changes so we would work under 5.4 perl.
50             # - Changes to docs to cleanup and reflect changes to code.
51             # - Added multi-valued option. Syntax is --arg ... - where
52             # the final '-' can be either the start of the next argument
53             # or a free-standing dash.
54             # - Fixed a problem with calculation of the indent for the
55             # help strings.
56             # - Added code to better check the non-dashed tags for validity.
57             # - Fixed a problem that was causing options to be dropped from
58             # the first line of the usage output.
59             #
60             # Revision 1.4 2005/01/18 03:44:02 sjs
61             # Added new other_values option.
62             # Added additional error checking.
63             # Added changes to support PERL 5.004.
64             # Modified USAGE message to also show mutual_exclusive options.
65             # Modified USAGE to separate long and short optional options.
66             #
67             # Revision 1.3 2005/01/17 06:54:57 sjs
68             #
69             # Makefile: move required version to 5.005.
70             # Bumped version to 2.
71             #
72             #
73             # Clean up documentaion.
74             # Make use of arg vs option more consistent.
75             # Get rid of 'our' variables so we could use 5.005 perl.
76             # Modified mutual_exclusive so it could take either a
77             # list or list of lists.
78             #
79             # Revision 1.2 2005/01/11 07:50:30 sjs
80             # Fixed mutual_exclude and required.
81             #
82             # Revision 1.1.1.1 2005/01/10 05:23:52 sjs
83             # Import of Getopt::OO
84             #
85             package Getopt::OO;
86              
87 1     1   15392 use 5.00404;
  1         3  
  1         40  
88 1     1   6 use strict;
  1         2  
  1         40  
89             # Use warnings if possible. Don't worry if you can't. Package was developed
90             # with warnings on, but it wasn't around by default before 5.6.
91             eval { require 'warnings.pm' };
92 1     1   5 use vars qw($VERSION @ISA @EXPORT_OK $Revision);
  1         6  
  1         4832  
93              
94             require Exporter;
95              
96             @ISA = qw(Exporter);
97              
98             @EXPORT_OK = qw(Debug Verbose);
99              
100             $VERSION = '0.07';
101             $Revision = '$Id:$';
102              
103             =head1 NAME
104              
105             Getopt::OO - An object oriented command line parser. It handles
106             short, long and multi (--x ... -) value options. It also incorporates
107             help for options to simplify generation of usage statements.
108              
109             =head1 SYNOPSIS
110              
111             use Getopt::OO qw(Debug Verbose);
112              
113             my ($handle) = Getopt::OO->new(\@ARGV,
114             '-d' => {
115             help => 'turn on debug output',
116             callback => sub {Debug(1); 0},
117             },
118             '-o' => {
119             help => 'another option.',
120             },
121             '-f' => {
122             help => 'option that expects one more value.',
123             n_values => 1,
124             },
125             '--long' {
126             help => 'long option'
127             },
128             '--multiple_' => {
129             help => [
130             "Everything between '--multiple_values' and '-' is",
131             "an value for this options",
132             ],
133             'multi_value' => 1,
134             'multiple= => 1, # Can happen more than once on command line.
135             },
136             other_values => {
137             help => 'file_1 ... file_n',
138             multi_value => 1,
139             },
140             );
141             if ($handle->Values()) {
142             Debug("You will get output if -d was on command line");
143             if (my $f = handle->Values(-f)) {
144             print "Got $f with the -f value.\n";
145             }
146             }
147             else {
148             print "No options found on command line.\n";
149             }
150              
151             =head1 DESCRIPTION
152              
153             Getopt::OO is an object oriented tool for parsing command line arguments.
154             It expects a reference to the input arguments and uses a perl hash
155             to describe how the command line arguments should be parsed. Note
156             that by parsed, we mean what options expect values, etc. We check
157             to make sure values exist on the command line as necessary -- nothing
158             else. The caller is responsible for making sure that a value that
159             he knows should be a file exists, is writable, or whatever.
160              
161             Command line arguments can be broken into two distinct types: options
162             and values that are associated with these options. In windows,
163             options often start with a '/' but sometimes with a '-', but
164             in unix they almost universally start with a '-'. For this module
165             options start with a '-'. We support two types of options:
166             the short single dashed options and the long double dashed options.
167             The difference between these two is that with this module the
168             short options can be combined into a single option, but the
169             long options can not. For example, most of us will be familiar
170             with the C command which can also be expressed
171             as C<-x -v -f file>. Long options can not be combined this way,
172             so '--help' for example must always stand by itself.
173              
174             The input template expects the option names as its keys. For instance
175             if you were expecting C<-xv --hello> as possible command line options,
176             the keys for your template hash would be C<-x>, C<-v>, and C<--hello>.
177              
178             =head1 Valid values for each dashed options are:
179              
180             =head2 help
181              
182              
183             A help string associated with the options.
184              
185             =head2 n_values
186              
187             Number of values the option expects. Any value greater than or
188             equal to 0 is valid with 0 being the default.
189              
190             =head2 multiple
191              
192             If this exists, it means the option may be encountered multiple times.
193             For example --
194              
195             '-a' => {
196             n_values => 3,
197             multiple => 1,
198             },
199              
200             says that if C<-a> is encountered on the command line, the next
201             three arguments on the command line are associated with it and
202             that it may be encountered multiple times.
203              
204              
205             =head2 multi_value
206              
207             Use this if you know that the option expects multiple values, but
208             you don't know how many till the user executes the script. This tag
209             is only valid for long options. Everything between the option and
210             a '-' is considered a value. For example, suppose you wanted to pass
211             in a group of user names, your command line might look like:
212             --users fred joe mary gandalf frodo -
213              
214             =head2 callback
215              
216             This must be a code reference. If the template entry looked like:
217              
218             '-a' => {
219             n_values => 1,
220             multiple => 1,
221             callback => \&xyz,
222             },
223              
224             then we would call the function xyz with the a Getopt::OO handle
225             and the option found and the argument reference. For instance
226             if the function looked like:
227              
228             sub Callback {
229             my ($handle, $option) = @_
230             ...
231              
232             the caller could get help with $handle->Help() or its values with
233             $handle->Values($option).
234              
235             Note that the only option information available at this point is
236             what has been found on the command line up to this point. For
237             example, if the callback were associated with the C<-f> option and
238             the command line looked like C<-xvfz 1 2 3>, we haven't yet parsed
239             the C<-z> option, so no information associated with this option
240             is available.
241              
242             If the callback returns a non-0 value, it failed. We
243             execute 'die $string' where $string is the returned value.
244              
245              
246             =head1 Template non-dashed arguments
247              
248             Only four non-dashed keys are allowed: 'usage', 'other_values',
249             'required', and 'mutual_exclusive'.
250              
251             =head2 usage
252              
253             This is a string. Typically it wil be the first part of a
254             help statement and combined with the 'help' arguments for
255             the various dashed arguments in the template, creates the complete
256             usage message. By default, we will create a usage string that
257             is the base name of the executable ($0) and just the string
258             '[options]'.
259              
260              
261             =head2 other_values
262              
263             Usually all the argments on a command line aren't associated
264             with options. For instance, a function may always require
265             a file name but have several other options too. It's
266             signature might look like
267              
268             script [-v] input_file
269              
270             other_values allows you to supply help for the usage message
271             and tell the parser how many args to expect. Use might look like
272              
273             other_values => {
274             help => 'file_1 ... file_n',
275             },
276              
277             For the call to script above, the first output line of
278             the usage statement would look like:
279              
280             script [-v] file_1 ... file_n
281              
282             and since multi_value is set, an error would occur unless at
283             least one value were passed in.
284              
285             Use multi_value or n_values to tell the parser how many values
286             to expect. Both of these values are optional and if not supplied,
287             the parser doesn't check for values after the parsing is done.
288              
289             help is also optional. If it is not supplied, we use n_values
290             or multi_value to print a message that makes sense. Note that
291             if n_values or multi_value are set, it is an error to not have
292             other values after the options are parsed, but you can just
293             supply the help value and no other checking of the other_values
294             will occur.
295              
296             As discussed below, other_values will also accept a callback and
297             use ClientData and return its values using
298             $handle->Values('other_values'). Unlike the other options,
299             other_values can not be 'multiple'.
300              
301             By default, any values not used by other arguments will get assigned
302             to the 'other_values' option. This is done mostly to allow error
303             checking. One of the decisions early in programming this module
304             was that I wanted to allow parsed arguments to start with a
305             '-'. Thus, something like
306              
307             --args => {'n_values' => 3},
308              
309             would allow a command line like '--args -a 1 5' and $h->Values('--args')
310             would return a 3 element array consisting of -a, 1, and 5. Unfortunatly
311             this makes both parsing and checking of command line arguments more
312             difficult. For example, if you had something like
313              
314             -a => {'n_values' => 2},
315              
316             and your command line looks like '-a 1 2 3 -s', the values after
317             3 don't get parsed and are left on the argument list.
318              
319             To simplify checking this situation, two changes were made
320             in version 0.07 of this module: 1) you can now set the 'other_values'
321             'n_values' option to 0 and we will die if any unparsed command
322             line values exist, or 2) unparsed command line values are now
323             placed on the 'other_values' option so you can use $h->Values('other_values')
324             to examine the un-parsed arguments.
325              
326             =head2 required
327              
328              
329             This is an array reference to required arguments. It is an error
330             if none of these are found on the command line.
331              
332             =head2 mutual_exclusive
333              
334             This is an list reference. It says "it is an error to receive
335             these arguments at the same time." For example, "tar cx" would not
336             make sense because you can't both create and extract at the
337             same time. Give a reference for each set of mutually exclusive
338             arguments. In the trivial case where you only have one set, the
339             argument can be just a reference to a list, but in the more complicated
340             case where you have sets of mutually exclusive arguments, this will
341             be a refrence to an list of list references. The template to express
342             this might look like:
343              
344             mutual_exclusive => [ qw( -x -c ) ],
345             -x => {
346             help => 'Extract a tar file',
347             },
348             -c => {
349             help => 'Create a tar file',
350             }
351              
352             As stated above, this would also be correct.
353              
354             mutual_exclusive => [
355             [qw( -x -c )],
356             ],
357             -x => {
358             help => 'Extract a tar file',
359             },
360             -c => {
361             help => 'Create a tar file',
362             }
363              
364             =head1 Methods associated with the OO module:
365              
366             =head2 my $handle = Getopt::OO->new(\@ARGV, %Template)
367              
368             Creator function. Expects a reference to the argument list and
369             a template that explanes how to parse the input arguments and returns
370             an object reference. If you want to catch parse errors
371             rather than having the parser print an error message and
372             exit, do this:
373              
374             my $handle = eval {Getopt::OO>new(\@ARGV, %template)};
375             if ($@) {...
376              
377             $@ will contain your error string if one exists and be empty
378             otherwise.
379              
380             =head2 $handle->Values(argument);
381              
382             Values() returns a list of command line options that
383             were matched in the order they were found. In scalar
384             context, this is the number of matches.
385              
386             Values($option) depends on the 'n_values' and the 'multiple'
387             for the option in the template. If the option had no
388             n_values element or n_values was 0, Values(option) will return
389             0 if the option was not found on the command line and 1 if
390             it was found. If n_values was set to 1 and multiple was not
391             set or was set to 0, we return nothing if the argument was
392             not found and the value of the argument if one was found.
393             If n_values > 1 and multiple was not set or if n_values is
394             1 and multiple was set, we return a list containing the
395             values if the values were found and nothing otherwise.
396             If the of n_values is greater than 1 and multiple is set,
397             we retrun a list of list references -- each contining n_values
398             elements, or nothing if no matches were found.
399              
400             The example below shows a template and accesing the values
401             returned by the parser. The template is ordered from the
402             simplest use to the most complex.
403              
404             Given the command line arguments:
405              
406             -abcde b c0 d0 d1 e0 e1 -c c1 -e e2 es
407            
408             and the following to create our GetOpt handle:
409              
410             use Getopt::OO qw(Debug);
411             my @argv = qw (-abcde b c0 d0 d1 e0 e1 -c c1 -e e2 es);
412             my $h = Getopt::OO->new(\@argv,
413             '-a' => {},
414             '-b' => { n_values => 1, },
415             '-c' => { n_values => 1, multiple => 1, },
416             '-d' => { n_values => 2, },
417             '-e' => { n_values => 2, multiple => 1, },
418             );
419             my $n_options = $h->Values();
420             my $a = $h->Values('-a');
421             my $b = $h->Values('-b');
422             my @c = $h->Values('-c');
423             my @d = $h->Values('-d');
424             my @e = $h->Values('-e');
425              
426             Example 1. ValuesDemo.pl
427              
428             =head2 my $help_string = $handle->Help();
429              
430             Get the string string we built for this template. Note
431             that this can be used to check the template to make sure
432             it is doing what you expect. It will contain optional
433             arguments separated from non optional, indicates required
434             and mutually exclusive options and indicates which options
435             expect values and how many values.
436              
437             =head2 my $client_data = $handle->ClientData($option);
438              
439             The ClientData method is supplied to allow data to be
440             associated with an option. The data must be scalar or
441             a reference. All calls to this method return what ever
442             the data was replied to, but it is only set if data is
443             passed in.
444              
445             To set the data:
446              
447             $h->ClientData($option, $x);
448              
449             To get the data:
450              
451             $x = $h->ClientData($option);
452              
453             =head1 Debug and Verbose Functions
454              
455             We also supply two functions the user can export. These are the
456             Debug and the Verbose functions. If the functions are exported
457             and we find --debug or --verbose in the command line arguments,
458             the associated function is enabled. These two functions behave
459             in multiplt ways: If called with just a '0' or '1', the function
460             is disabled or disabled. If called with no arguments, we return
461             the state of the function: 0 if disabled and 1 if enabled. If
462             called with a list and the first element of the list looks
463             like a printf format statement, we behave like printf, and
464             otherwise we behave like a simple print statement. If the
465             function is called with a single argument that is a reference
466             to an IO::File object, we will attempt to send all further output
467             to this handle. Note that the object must be enabled before
468             any output will occur though.
469              
470             =head1 EXPORT
471              
472             None by default.
473              
474             =head1 SEE ALSO
475              
476             Several example scripts are included in the release under
477             the directory 'Demo'.
478              
479              
480             =head1 AUTHOR
481              
482             Steven Smith, Esjs@chaos-tools.comE
483              
484             =head1 COPYRIGHT AND LICENSE
485              
486             Copyright (C) 2004 by Steven Smith
487              
488             This library is free software; you can redistribute it and/or modify
489             it under the same terms as Perl itself, either Perl version 5.8.3 or,
490             at your option, any later version of Perl 5 you may have available.
491              
492             =cut
493              
494             {
495             # Debug and Verbose are functions used to enable
496             # and disable debug output.
497             # to use:
498             # To send subsequent output to $fh if $ffh is an IO::File file handle.
499             # Debug($fh);
500             # Debug(1); turns on debug output.
501             # Debug(0); turns of debug output.
502             # Debug("%2d\n", $x); for printf style output.
503             # Debug($string); for print style output.
504             # Verose behaviour is identical to Debug output.
505             # Any call to Debug returns its state -- on or off.
506             # Generic routine called from Debug and Verbose.
507             sub _print_ {
508 16     16   23 my $fh_ref = shift @_;
509 16         22 my $enabled_ref = shift @_;
510 16 100 66     180 if (defined $_[0] && @_ == 1
    100 66        
      66        
      100        
511             && (
512             $_[0] =~ /^[01]$/
513             || (ref $_[0] && ref $_[0] eq 'IO::File')
514             )
515             ) {
516 10 100       21 if (ref $_[0]) {
517 2         11 $$fh_ref = $_[0];
518             }
519             else {
520 8         27 $$enabled_ref = $_[0];
521             }
522             }
523             elsif ($$enabled_ref && @_) {
524 2 50       7 if ($_[0] =~ /\%\d*[sdfcx]/i) {
525 0         0 my $format = shift @_;
526 0         0 $$fh_ref->printf($format, @_);
527             }
528             else {
529 2         17 $$fh_ref->print (@_);
530             }
531             }
532 16         68 return($$enabled_ref);
533             }
534             # Verbose function.
535             {
536             my $fh = do {local *STDOUT};
537             my $verbose = 0;
538 8     8 0 506 sub Verbose {return(_print_(\$fh, \$verbose, @_)); }
539             }
540             # Debug function.
541             {
542             my $fh = do {local *STDOUT};
543             my $debug = 0;
544 8     8 0 13094 sub Debug {return(_print_(\$fh, \$debug, @_)); }
545             }
546             }
547              
548             # Build and return a help string from the imput template.
549             sub build_help {
550             sub _short_args_list_ {
551 76     76   135 my ($template, @list) = @_;
552 76         80 my (@options, @args);
553 76         211 foreach my $option (sort @list) {
554 28         91 my $o = ($option =~ /^-(.)/)[0];
555 28         49 push @options, $o;
556 28 100       106 if ($template->{$option}{'n_values'}) {
557 7         19 foreach my $i (0..($template->{$option}{'n_values'} - 1)) {
558 9 100       43 push @args, "${o}_arg" . (($i) ? (${i} + 1) : '');
559             }
560             }
561             }
562 76 100       412 (@options)
563             ? return('-' . join('', @options) . ' ' . join(' ', @args))
564             : return('');
565             }
566             sub _long_args_list_ {
567 76     76   124 my ($template, @list) = @_;
568 76         94 my (@options);
569 76         186 foreach my $option (sort @list) {
570 11         13 push @options, $option;
571 11 100       33 if ($template->{$option}{'n_values'}) {
572 1         6 my $o = ($option =~ /^--(.*)/)[0];
573 1         4 foreach my $i (0..($template->{$option}{'n_values'} - 1)) {
574 1 50       6 $options[-1] .= " ${o}_arg" . (($i) ? ${i} : '');
575             }
576             }
577 11 100       31 if ($template->{$option}{'multi_value'}) {
578 6         15 $options[-1] .= ' ... -'
579             }
580             }
581 76 100       432 (@options)
582             ? return(join(' ', @options))
583             : return('');
584             }
585              
586 38     38 0 56 my ($template) = @_;
587 38         249 my $name = ($0 =~ m{^(?:.*/)*(.*)})[0];
588 7         23 my %required = (exists $template->{'required'})
589 38 100       112 ? (map {$_, 1} @{$template->{'required'}})
  5         13  
590             : ();
591 38   100     386 my @optional = grep /^-/ && !/^--/ && !$required{$_}, keys %$template;
592 38   100     370 my $short_optional_arg_list = _short_args_list_ (
593             $template,
594             grep(/^-/ && !/^--/ && !$required{$_}, keys %$template),
595             );
596 38   100     229 my $long_optional_arg_list = _long_args_list_ (
597             $template,
598             grep(/^--/ && !$required{$_}, keys %$template),
599             );
600 38   100     374 my $short_required_arg_list = _short_args_list_ (
601             $template,
602             grep(/^-/ && !/^--/ && $required{$_}, keys %$template),
603             );
604 38   100     217 my $long_required_arg_list = _long_args_list_ (
605             $template,
606             grep(/^--/ && $required{$_}, keys %$template),
607             );
608 38         56 my $other_values = do {
609 38         50 my $rv = '';
610 38 100       108 if ($template->{'other_values'}) {
611 17         26 my $ref = $template->{'other_values'};
612 17 100 66     97 if (ref $ref && ref $ref eq 'HASH') {
613 16 100       212 $rv = ($ref->{'help'})
    100          
    100          
    100          
    100          
    100          
614             ? " $ref->{help}"
615             : ($ref->{multi_value})
616             ? ' value_1 ... value_n'
617             : ($ref->{n_values})
618             ? ($ref->{n_values} !~ /^\d+$/)
619             ? ''
620             : ($ref->{n_values} == 1)
621             ? ' value'
622             : ($ref->{n_values} == 2)
623             ? ' value_1 value_2'
624             : " value_1 ... value_"
625             . $ref->{n_values}
626             : '';
627             }
628             }
629 38         73 $rv;
630             };
631 38 100       242 my $usage = join ('', "USAGE: $name",
    100          
    100          
    100          
632             ($short_optional_arg_list) ? " [$short_optional_arg_list]" : '',
633             ($long_optional_arg_list) ? " [$long_optional_arg_list]" : '',
634             ($short_required_arg_list) ? " $short_required_arg_list" : '',
635             ($long_required_arg_list) ? " $long_required_arg_list" : '',
636             $other_values,
637             ) . "\n";
638             # the template usage may be either a scalar or a list ref.
639             # in either case, indent by 4 spaces and terminate with a
640             # linefeed.
641 38 50       89 if($template->{'usage'}) {
642 0         0 my @use = map {" $_\n"}
  0         0  
643             (ref $template->{'usage'})
644 0 0       0 ? @{$template->{'usage'}}
645             : ($template->{'usage'});
646 0         0 $usage .= join('', @use);
647             }
648 38 100       83 if (%required) {
649 5         19 my @r = sort keys %required;
650 5 100       26 $usage .= (@r > 1)
651             ? " Arguments " . join(', ', @r) . " are required.\n"
652             : " Argument @r is required.\n";
653             }
654 38 100       108 if (my $mutual_exclusive = $template->{'mutual_exclusive'}) {
655 3 50       8 if (ref $mutual_exclusive->[0]) {
656 3         8 my @r = @$mutual_exclusive;
657 3         14 $usage .= " Arguments \""
658 3         6 . join("\", \"", map {"@$_"} @r)
659             . "\" are mutually exclusive.\n";
660             }
661             else {
662 0         0 $usage .= " Arguments \"@{$mutual_exclusive}\""
  0         0  
663             . " are mutually excluive.\n";
664             }
665             }
666 38 100 100     453 if (my @m = grep /^-/ && $template->{$_}{'multiple'}, keys %$template) {
667 3 100       18 $usage .= join('',
668             (@m > 1)
669             ? " Arguments " . join(', ', sort @m)
670             : " Argument @m",
671             " may occur more than once.\n",
672             );
673             }
674              
675 38         66 my %options_list;
676 38         44 my $max_len = 0;
677 38         45 my @help;
678 13         20 map {
679 38   100     447 my $options = $_;
680             # add 'arg' for each value in n_values.
681 13 100       44 if ($template->{$_}{'n_values'}) {
    100          
682 3         8 foreach my $i (1..$template->{$_}{'n_values'}) {
683 3 50       24 $options .= ($i > 1) ? " arg_$i" : ' arg';
684             }
685             }
686             elsif ($template->{$_}{'multi_value'}) {
687 2         4 $options .= ' ... -';
688             }
689 13         21 $options_list{$_} = $options;
690 13 100       52 $max_len = length $options if (length $options > $max_len);
691             } sort grep ref $template->{$_} eq 'HASH'
692             && /^-+/
693             && exists $template->{$_}{'help'}
694             , keys %$template;
695 38         100 $max_len = (int($max_len / 4) + 1) * 4;
696             # output is set so that the arg_list is put out the
697             # first time only and all the actual help is justified
698             # to the right of the argument list.
699 38         134 foreach my $key (sort keys %options_list) {
700             # the help element may be either a string or a list ref.
701             # output should look like:
702             # -a value first line of help
703             # second line of help
704             # etc and so on.
705 0         0 my @help_list = (ref $template->{$key}{'help'})
706 13 50       59 ? @{$template->{$key}{'help'}}
707             : ($template->{$key}{'help'});
708 13         18 my $h = $options_list{$key};
709 13         46 map {
710 13         18 push @help, sprintf(" %-${max_len}s%s\n", $h, $_);
711 13         37 $h = ''
712             } @help_list;
713             }
714 38         232 return(join('', $usage, @help));
715             }
716              
717             # Parse the template for correctness.
718             # Make sure we have only valid arguments for each of the
719             # elements of the template.
720             sub parse_template {
721 36     36 0 49 my ($this, $template) = @_;
722 36         45 my @errors;
723             my %defined;
724 36 100       88 if (defined $template->{'other_values'}) {
725 17         29 my $ref = $template->{'other_values'};
726 17 100 66     93 if (ref $ref && ref $ref eq 'HASH') {
727             # These are valid tags for the other_values key.
728 80         177 my %valid_tags = map {
729 16         28 $_, 1
730             } qw(multi_value n_values help callback required);
731 16 100 100     248 if (my @bad = grep !$valid_tags{$_}, keys %$ref) {
    100          
    100          
732 1         5 push @errors, "other_values: bad tags: @bad\n";
733             }
734             elsif ($ref->{multi_value}) {
735 1         4 push @errors,
736             "other_values: Can't have multi_value\n";
737             }
738             elsif ($ref->{n_values} && $ref->{n_values} !~ /^\d+/) {
739 1         3 push @errors, "other_values: n_values must be a number.\n";
740             }
741             }
742             else {
743 1         2 push @errors, "other_values: should be reference to a hash.\n";
744             }
745 17 100       48 %{$this->{other_values}} = %{$template->{other_values}} unless @errors;
  13         51  
  13         31  
746             }
747              
748 36         161 foreach my $option (sort grep !/^-+/, keys %$template) {
749 25         45 my $ref = $template->{$option};
750 25 100       84 if ($option eq 'mutual_exclusive') {
    100          
751 3 50       10 unless (ref $ref eq 'ARRAY') {
752 0         0 push @errors, "Bad mutual_exclusive argument. Should be ",
753             "a list or a list of lists.\n";
754             }
755             }
756             elsif ($option eq 'required') {
757 5 50 33     27 unless (ref $ref && ref $ref eq 'ARRAY') {
758 0         0 push @errors, "required should be a list reference.\n";
759             }
760             }
761 25 100       96 last if @errors;
762             }
763 36         181 foreach my $option (sort grep /^-+/, keys %$template) {
764 38 100       171 if ($option =~ /^-[a-zA-Z]\w+/) {
765 1         6 push @errors, "Bad template option: \"$option\". Short arguments "
766             . "(i.e. arguments starting with a\n single dash) "
767             . "can not be longer than one character.\n";
768 1         2 last;
769             }
770 37         56 my $ref = $template->{$option};
771 37         165 my @bad = grep !/^(help|n_values|multiple|multi_value|callback)$/
772             , keys %$ref;
773 37 50       74 if (@bad) {
774 0         0 push @errors, "$option: \"@bad\" are not recognized "
775             . "options.\n";
776             }
777             else {
778 37         89 foreach my $key (sort keys %$ref) {
779 32 100       61 if ($key eq 'n_values') {
780 8 50       46 if ($ref->{'n_values'} !~ /^\d+$/) {
781 0         0 push @errors,
782             "$key: n_values is $ref->{'n_values'} and should be an ",
783             "integer\n";
784             }
785             }
786             # Make sure keys for template entry are valid.
787 32 100       66 if ($ref->{'multi_value'}) {
788 9 50       23 if ($option =~ /^--/) {
789 9 50       38 if (my @b = grep /^(n_values)$/, keys %$ref) {
790 0         0 push @errors, "$key is multi value. \"@b\" are not "
791             . "valid for this option.";
792             }
793             }
794             else {
795 0         0 push @errors, "$option is a short option. multi_value is "
796             . "only valid for long options.\n";
797             }
798             }
799 32 50       87 last if @errors;
800             }
801             }
802 37 50       105 %{$this->{$option}} = %{$template->{$option}} unless @errors;
  37         155  
  37         72  
803             }
804 36 100       7193 (@errors) ? return(@errors) : return;
805             }
806             sub parse_options {
807 31     31 0 135 my ($this, $argv, $template) = @_;
808 31         140 my @errors = (); $this->{'errors'} = \@errors;
  31         78  
809 31         49 my @options_found = (); $this->{'options'} = \@options_found;
  31         130  
810 31   100     372 while (@$argv && $argv->[0] =~ /^-/ && !@errors) {
      66        
811             # If the option starts with a single dash, split it into smaller
812             # one character args preceeded by a dash.
813             my @options = ($argv->[0] =~ /^--/)
814             ? ($argv->[0])
815 27 100       82 : do {
816 17         230 my $a = ($argv->[0] =~ /^-(.*)/)[0];
817 17         47 map {"-$_"} split //, $a;
  21         66  
818             };
819 27         40 shift @$argv;
820 27         74 while (defined (my $option = shift @options)) {
821 31 50       67 if ($template->{$option}) {
822 31         47 push @options_found, $option;
823 31         255 my $ref = $template->{$option};
824             # If this option has already been encountered and multiple
825             # isn't set, we have an error.
826 31 100 100     165 if (exists $this->{$option}{'exists'} && !$ref->{'multiple'}) {
    100          
    100          
827 1         4 push @errors,
828             "$option encountered more than once and multiple ",
829             "is not set.\n";
830             }
831             # If we have n_values set, we're pulling one or more
832             # values off the command line for this argument.
833             elsif (my $n_values = $ref->{'n_values'}) {
834 7         15 $this->{$option}{'n_values'} = $ref->{'n_values'};
835 7   100     32 $this->{$option}{'multiple'} = $ref->{'multiple'} || 0;
836             # If n_values is greater than 1, pull the next
837             # n_values values off of the command line and save
838             # it in the values list as an array ref.
839 7 100       16 if ($n_values > 1) {
840 3         4 my @in;
841 3   66     4 do {
842 6 50       10 if (@$argv) {
843 6         29 push @in, shift @$argv;
844             }
845             else {
846 0         0 push @errors,
847             "Insufficent values for $option\n";
848             }
849             } while (--$n_values && !@errors);
850             # Multiple, we save it as a list of lists,
851             # non-multiple, save as a list ref.
852 3 100       8 if ($ref->{'multiple'}) {
853 2         3 push(@{$this->{$option}{'values'}}, \@in);
  2         6  
854             }
855             else {
856 1         3 $this->{$option}{'values'} = \@in;
857             }
858             }
859             else {
860 2         5 (@$argv)
861             ? ($this->{$option}{'multiple'})
862 4 100       22 ? push(@{$this->{$option}->{'values'}},
    50          
863             shift @$argv)
864             : ($this->{$option}{'values'} = shift @$argv)
865             : push @errors, "Insufficent values for $option\n";
866             }
867             }
868             elsif ($this->{$option}{'multi_value'}) {
869 6         8 my @o;
870 6   100     30 while (@$argv && $argv->[0] !~ /^-/) {
871 18         81 push @o, shift @$argv;
872             }
873 6 100       12 if(@$argv) {
874 5 50       13 shift @$argv if $argv->[0] eq '-';
875 5 100       15 if ($this->{$option}{'multiple'}) {
876 2 100       6 unless (exists $this->{$option}{'values'}) {
877 1         3 $this->{$option}{'values'} = [];
878             }
879 2         3 push @{$this->{$option}{'values'}}, \@o;
  2         7  
880             }
881             else {
882 3         5 @{$this->{$option}{'values'}} = @o;
  3         12  
883             }
884             }
885             else {
886 1         5 push @errors, "Failed to find end to "
887             . "multi_value option $option.\n";
888             }
889             }
890             # n_values isn't set. Just increment the values for
891             # this guy.
892             else {
893 17         37 $this->{$option}->{'values'}++;
894             }
895 31 100 100     149 if (!@errors && $ref->{'callback'}) {
896 2 100       3 if (my $error = &{$ref->{'callback'}}($this, $option)) {
  2         8  
897 1         10 push @errors, "Option callback for \"$option\" "
898             . "returned an error:\n\t$error\n";
899             }
900             }
901             }
902             else {
903 0         0 push @errors, "unrecognized option: $option\n";
904             }
905 31         121 $this->{$option}{'exists'}++;
906             }
907 27 100       158 last if @errors;
908             }
909             # Initialize othe_values values. Set its exists to the number
910             # of values in it.
911 31         92 $this->{other_values}{'exists'} = @$argv;
912 31 100       106 $this->{other_values}{'values'} = [@$argv] if @$argv;
913 31 100 66     136 if ($template->{'other_values'} && !@errors) {
914 13         26 my $ref = $template->{'other_values'};
915 13 100 100     80 if (exists $ref->{'n_values'} && $ref->{'n_values'} == 0 && @$argv) {
      66        
916 1         5 push @errors, "other_values n_values set to 0 but received "
917             . scalar @$argv, " values.\n";
918             }
919             else {
920 12   100     41 my $n = $ref->{'n_values'} || 0;
921 12 100 100     88 if ($n && @$argv && $n != @$argv) {
      100        
922 2         70 push @errors, "other_values got "
923             . scalar @$argv
924             . " values and expected $n\n";
925             }
926             else {
927 10 100       42 $this->{'other_values'}{'values'} =
928             ($n == 1) ? $argv->[0] : [@$argv];
929             }
930             # If we have an other_values callback, do it.
931 12 100 100     103 if (!@errors && $ref->{'callback'}) {
932 3 100       5 if (my $error = &{$ref->{'callback'}}($this, 'other_values')) {
  3         13  
933 1         9 push @errors, "other_values callback returned an error:\n\t"
934             . "$error\n";
935             }
936             }
937             }
938             }
939             }
940              
941             # Object creater.
942             sub new {
943 38     38 1 2401 my $self = shift @_;
944 38         51 my (@errors, $this, @mutual_exclusive, @required);
945             # Check for correctness of input arguments.
946 38 50 33     236 if (!ref $_[0] || ref $_[0] ne 'ARRAY') {
947 0         0 push @errors, "Usage: Getopt::OO::new(ref array, hash);\n",
948             "first argment must be a reference to an array.\n";
949             }
950             else {
951             # Check for an odd number of elements in the @_. This is
952             # even for the hash +1 for the argv reference.
953 38 50       106 unless (@_ & 1) {
954 0         0 push @errors, "Usage: Getopt::OO::new(ref array, hash);\n",
955             "hash has an odd number of elements.\n";
956             }
957             }
958 38 50       162 my ($argv, %template) = @_ unless @errors;
959 38         101 $this->{'help'} = build_help(\%template);
960             # check valid options. Do this after help so we get a
961             # help message -- even if it's bogus.
962 38         72 my %valid = map {$_,1} qw(
  152         387  
963             other_values usage required mutual_exclusive
964             );
965 38 100 100     315 if (my @bad = grep !/^-/ && !$valid{$_}, keys %template) {
966 1         8 push @errors, "Unrecognized tags: @bad\n";
967             }
968 38         101 bless($this, $self);
969 38 100       90 unless (@errors) {
970             # Check odd elements for uniqueness. We must check before
971             # the template before it becomes a hash or we lose the
972             # error that the same option was declared multiple times.
973 37         48 my %keys;
974 37         44 my $i = 0;
975 37 100 100     2404 if (my @bad = grep $i++ && $keys{$_}++, @_) {
976 1         5 push @errors, "Options \"@bad\" declared more than once.\n";
977             }
978             }
979 38 100       94 unless (@errors) {
980             # Build help first so we have something to print on error exit.
981              
982             # Check to make sure we have valid input args. All args must have
983             # 1 or 2 leading dashes or be 'required', 'mutual_exclusive' or
984             # 'usage'.
985 36         88 @errors = parse_template($this, \%template);
986             }
987 38 100       108 unless (@errors) {
988 31         170 parse_options($this, $argv, \%template);
989 31 50       87 @errors = (exists $this->{'errors'}) ? @{$this->{'errors'}} : ();
  31         75  
990             }
991             # Check for required options.
992 38 100       752 unless (@errors) {
993 7         21 my %required = ($template{'required'})
994 24 100       62 ? map {$_, 1} @{$template{'required'}}
  5         12  
995             : ();
996 24 100       68 if (%required) {
997             # pull any required options we encountered out,
998             # compare the number of required found against
999             # the number of required options and if they are
1000             # different, figure out what's missing and make
1001             # an error message.
1002 5         9 my %x;
1003 5   100     159 my @r = grep !$x{$_}++ && $required{$_} && $this->{$_}{'exists'}
1004             , keys %$this;
1005 5 100 66     35 unless(@r && @r == scalar(keys %required)) {
1006 2         6 my %r = map {$_,1} @r;
  0         0  
1007 2         10 my @missing = grep !$r{$_}, keys %required;
1008 2         15 push @errors, "Missing required options: @missing\n";
1009             }
1010             }
1011             }
1012             # Check for mutually exclusive options.
1013 38 100       86 unless (@errors) {
1014 22 100       61 if (exists $template{mutual_exclusive}) {
1015 3 50       8 if (ref $template{mutual_exclusive}) {
1016 3         4 my @mutual_exclusive = @{$template{mutual_exclusive}};
  3         8  
1017 3   100     62 my @options = grep $_ =~ /^-/ && $this->{$_}{'exists'}, keys %$this;
1018 3 50       9 if (ref $mutual_exclusive[0]) {
1019 3         5 foreach my $ref (@mutual_exclusive) {
1020 3         5 my %check_hash = map {$_, 1} @$ref;
  6         16  
1021 3 100       20 if ((my @bad = grep $check_hash{$_}, @options) > 1) {
1022 1         6 push @errors, "Found mutually exclusive options: ",
1023             "@bad\n";
1024             }
1025             }
1026             }
1027             # simple case: this could be just a list.
1028             else {
1029 0         0 my %check_hash = map {$_, 1} @mutual_exclusive;
  0         0  
1030 0 0       0 if ((my @bad = grep $check_hash{$_}, @options) > 1) {
1031 0         0 push @errors, "Found mutually exclusive options: ",
1032             "@bad\n";
1033             }
1034             }
1035             }
1036             else {
1037 0         0 die "argument to mutual_exclusive should be an ",
1038             "array reference.\n";
1039             }
1040             }
1041             }
1042 38 100       170 if (@errors) {
1043 17         211 die $this->{'help'}, "Found following errors:\n", @errors;
1044             }
1045 21         109 return($this);
1046             }
1047 12     12 1 205 sub Help {return $_[0]->{'help'}}
1048             # If no key is given, return the number of options found.
1049             # If single value and no multiple set, unless user wants an
1050             # array back, return a scalar. If they want an array, give
1051             # 'em an array.
1052             # If user wants multiple value single time, give 'em an
1053             # array back.
1054             # If user wants multiple value multiple times, give 'em a
1055             # an array of list ref's.
1056             sub Values {
1057 24     24 1 174 my ($this, $key) = @_;
1058 24 100       156 if ($key) {
1059 18 50       37 if (exists $this->{$key}) {
1060 18         29 my $ref = $this->{$key};
1061 18 100       39 if (exists $ref->{'values'}) {
1062 16 100       105 if ($ref->{'multi_value'}) {
    100          
1063 4         4 return (@{$ref->{'values'}})
  4         21  
1064             }
1065             elsif ($ref->{'n_values'}) {
1066 7 100       22 if ($ref->{'multiple'}) {
    100          
1067 2         3 return(@{$ref->{'values'}})
  2         8  
1068             }
1069             elsif ($ref->{'n_values'} == 1) {
1070 1         4 return($ref->{'values'})
1071             }
1072             else {
1073 4         6 return(@{$ref->{'values'}})
  4         18  
1074             }
1075             }
1076             else {
1077             return(
1078 2         12 (wantarray())
1079             ? (ref $ref->{'values'}
1080             && ref $ref->{'values'} eq 'ARRAY')
1081 5 50 33     34 ? @{$ref->{'values'}}
    100          
1082             : ($ref->{'values'})
1083             : $ref->{'values'}
1084             );
1085             }
1086             }
1087             else {
1088 2         9 return;
1089             }
1090             }
1091             else {
1092 0         0 die "Values called undefined option: $key\n";
1093             }
1094             }
1095             else {
1096 6         8 my @rv = @{$this->{'options'}};
  6         19  
1097 6 100       19 push @rv, 'other_values' if $this->{'other_values'}{'exists'};
1098 6 100       35 (@rv) ? return(@rv) : return;
1099             }
1100             }
1101              
1102             sub ClientData {
1103 3     3 1 16 my ($this, $option, $data) = @_;
1104 3 50 33     18 if ($option && $this->{$option}) {
1105 3 100       13 $this->{$option}{'client_data'} = $data if @_ == 3;
1106             }
1107             else {
1108 0         0 die "ClientData called on undefined option.\n";
1109             }
1110 3 100       14 (exists $this->{$option}{'client_data'})
1111             ? return($this->{$option}{'client_data'})
1112             : return;
1113             }
1114             1;
1115              
1116             __END__