File Coverage

blib/lib/Getopt/Fancy.pm
Criterion Covered Total %
statement 9 149 6.0
branch 0 68 0.0
condition 0 21 0.0
subroutine 3 12 25.0
pod 6 9 66.6
total 18 259 6.9


line stmt bran cond sub pod time code
1             package Getopt::Fancy;
2              
3 1     1   23678 use strict;
  1         3  
  1         47  
4 1     1   1297 use Getopt::Long;
  1         15052  
  1         7  
5              
6 1     1   174 use vars qw($VERSION);
  1         6  
  1         1720  
7              
8             $VERSION = "0.06";
9              
10             # GT = GetOptions spefication (=i, :s, etc)
11             # EX = Example arg
12             # DESC = Description of arg
13             # DEF = Default value
14             # REQ = Required arg
15             # ALLOWED = List of allowed values
16             # COMMAS = Allow comma separated values for multi valued guys
17             # SECTION = The section the arg belongs under (when printing usage)
18             # REGEX = regex that the arg has to match
19              
20             Getopt::Long::Configure ("no_ignore_case");
21              
22             our %config;
23             our %intvars;
24            
25             sub new
26             {
27 0     0 1   my $type = shift;
28 0   0       my $class = ref($type) || $type;
29 0           my $self = bless {}, $class;
30 0           $intvars{$self}->{maxexlen} = 0;
31 0           $intvars{$self}->{maxoptlen} = 0;
32 0           return $self;
33             }
34              
35             sub add
36             {
37 0     0 1   my $self = shift;
38 0           my $key = shift;
39 0           my %values = @_;
40 0           my ($aref, $val);
41 0           my $use_yiv = 1;
42              
43 0 0         return unless $key;
44 0 0         $intvars{$self}->{maxoptlen} = length ($key) if (length($key) > $intvars{$self}->{maxoptlen});
45 0 0 0       $intvars{$self}->{maxexlen} = length ($values{EX}) if ($values{EX} && length($values{EX}) > $intvars{$self}->{maxexlen});
46 0 0         if ($values{YIV}) {
47 0 0         if (! ref $values{YIV}) {
48 0           $aref = [$values{YIV}];
49             } else {
50 0           $aref = $values{YIV};
51             }
52 0           foreach $val (@{$aref}) {
  0            
53 0 0 0       if (length($val) == 0 || $val =~ m/\$\(.*?\)/o) {
54 0           $use_yiv = 0;
55 0           last;
56             }
57             }
58 0 0         $values{DEF} = $values{YIV} if $use_yiv;
59             }
60 0           $config{$self}->{$key} = \%values;
61             }
62              
63             sub get_values
64             {
65 0     0 1   my $self = shift;
66 0           my ($key, $result, $values);
67 0           my $spaces = " " x ($intvars{$self}->{maxoptlen} + 5);
68 0           my $maxoptlen = $intvars{$self}->{maxoptlen};
69              
70 0           foreach $key (keys %{$self}) {
  0            
71 0 0         if (! ref $self->{$key}) {
72 0           $values = [$self->{$key}];
73             } else {
74 0           $values = $self->{$key};
75             }
76 0           $result .= sprintf (" %-${maxoptlen}s => %s", $key, join("\n$spaces", @{$values}));
  0            
77 0           $result .= "\n";
78             }
79 0           return $result;
80             }
81              
82             sub get_error
83             {
84 0     0 1   my $self = shift;
85 0           return $intvars{$self}->{error_msg};
86             }
87              
88             sub get_options
89             {
90 0     0 1   my $self = shift;
91 0           my ($key, $values, $value);
92              
93             # Set the =i, =s stuff
94 0           my @gopts = map {$_ .= $config{$self}->{$_}->{GT};} keys %{$config{$self}};
  0            
  0            
95              
96             # Get the options
97 0 0         if (!GetOptions($self, @gopts)) {
98 0           $intvars{$self}->{error_msg} = "Invalid option.\n";
99 0           return ($intvars{$self}->{error_msg});
100             }
101              
102             # Set the default values
103 0           foreach $key (keys %{$config{$self}}) {
  0            
104 0 0         next unless (defined $config{$self}->{$key}->{DEF});
105 0 0         next if (defined $self->{$key});
106 0 0 0       if ($config{$self}->{$key}->{GT} &&
      0        
107             index($config{$self}->{$key}->{GT}, "@") > 0 &&
108             !ref $config{$self}->{$key}->{DEF}) {
109 0           $self->{$key} = [$config{$self}->{$key}->{DEF}];
110             } else {
111 0           $self->{$key} = $config{$self}->{$key}->{DEF};
112             }
113             }
114              
115             # Expand any comma separated lists
116 0           foreach $key (keys %{$config{$self}}) {
  0            
117 0 0 0       next unless ($config{$self}->{$key}->{GT} && index($config{$self}->{$key}->{GT}, "@") > 0);
118 0 0         next unless ($config{$self}->{$key}->{COMMAS});
119 0 0         next unless (defined $self->{$key});
120 0           $values = $self->{$key};
121 0           $self->{$key} = [];
122 0           foreach $value (@{$values}) {
  0            
123 0           push @{$self->{$key}}, split(/\s*,\s*/, $value);
  0            
124             }
125             }
126              
127              
128             # Check for required values
129 0           foreach $key (keys %{$config{$self}}) {
  0            
130 0 0 0       $intvars{$self}->{error_msg} .= "$key is required, but missing\n" if ($config{$self}->{$key}->{REQ} && ! defined $self->{$key});
131             }
132              
133             # Check for REGEX conformity
134 0           foreach $key (keys %{$config{$self}}) {
  0            
135 0 0         next unless defined ($config{$self}->{$key}->{REGEX});
136 0 0         next unless defined ($self->{$key});
137 0 0         if (! ref $self->{$key}) {
138 0           $values = [$self->{$key}];
139             } else {
140 0           $values = $self->{$key};
141             }
142 0           foreach $value (@{$values}) {
  0            
143 0 0         $intvars{$self}->{error_msg} .= "$value not a valid value for $key. Does not match regex: ".$config{$self}->{$key}->{REGEX}."\n" if ($value !~ m/$config{$self}->{$key}->{REGEX}/);
144             }
145             }
146              
147             # Check for allowed values
148 0           foreach $key (keys %{$config{$self}}) {
  0            
149 0 0         next unless defined ($config{$self}->{$key}->{ALLOWED});
150 0 0         next unless defined ($self->{$key});
151 0           my $allowed;
152             my %a;
153 0 0         if (! ref $config{$self}->{$key}->{ALLOWED}) {
154 0           $allowed = [$config{$self}->{$key}->{ALLOWED}];
155             } else {
156 0           $allowed = $config{$self}->{$key}->{ALLOWED};
157             }
158 0           map {$a{$_} = 1;} @{$allowed};
  0            
  0            
159            
160 0 0         if (! ref $self->{$key}) {
161 0           $values = [$self->{$key}];
162             } else {
163 0           $values = $self->{$key};
164             }
165 0           foreach $value (@{$values}) {
  0            
166 0 0         $intvars{$self}->{error_msg} .= "$value not a valid value for $key. Allowed values: " . join(", ", @{$allowed}) . "\n" unless ($a{$value});
  0            
167             }
168             }
169 0           return $intvars{$self}->{error_msg};
170             }
171              
172             sub check_for
173             {
174 0     0 0   my $self = shift;
175 0           my $key = shift;
176 0           my $value = shift;
177 0           my $item;
178              
179 0           foreach $item (keys %{$config{$self}}) {
  0            
180 0 0         return 1 if ($config{$self}->{$item}->{$key} == $value);
181             }
182 0           return 0;
183             }
184              
185             sub have_required
186             {
187 0     0 0   my $self = shift;
188 0           return $self->check_for("REQ", 1);
189             }
190              
191             sub have_optional
192             {
193 0     0 0   my $self = shift;
194 0           return $self->check_for("REQ", 0);
195             }
196              
197              
198             sub get_usage
199             {
200 0     0 1   my $self = shift;
201 0           my $options = shift;
202             # my $req_only = shift;
203 0           my $spaces = " " x ($intvars{$self}->{maxexlen} + $intvars{$self}->{maxoptlen} + 7);
204 0           my $maxexlen = $intvars{$self}->{maxexlen};
205 0           my $maxoptlen = $intvars{$self}->{maxoptlen};
206 0           my ($result, $key, $defs, @keys);
207 0           my $section = "";
208              
209 0 0         if (defined $options) {
210 0           @keys = @{$options};
  0            
211             } else {
212 0 0         @keys = sort { $config{$self}->{$a}->{SECTION} cmp $config{$self}->{$b}->{SECTION} or $a cmp $b} keys %{$config{$self}};
  0            
  0            
213             }
214              
215 0           foreach $key (@keys) {
216 0           my $req = "";
217             # if (defined $req_only) {
218             # next if ($req_only && !$config{$self}->{$key}->{REQ});
219             # next if (!$req_only && $config{$self}->{$key}->{REQ});
220             # }
221 0 0         if (! ref $config{$self}->{$key}->{DEF}) {
222 0           $defs = [$config{$self}->{$key}->{DEF}];
223             } else {
224 0           $defs = $config{$self}->{$key}->{DEF};
225             }
226 0 0         if ($section ne $config{$self}->{$key}->{SECTION}) {
227 0           $section = $config{$self}->{$key}->{SECTION};
228 0           $result .= "\n [${section}]:\n";
229             }
230              
231 0 0         $req = "[REQ] " if $config{$self}->{$key}->{REQ};
232 0 0         $config{$self}->{$key}->{DESC} =~ s/\n/\n$spaces/og if $config{$self}->{$key}->{DESC};
233 0           $result .= sprintf " -%-${maxoptlen}s %-${maxexlen}s : ${req}%s", $key, $config{$self}->{$key}->{EX}, $config{$self}->{$key}->{DESC};
234 0 0         $result .= "\n${spaces}Default = " . join(", ", @{$defs}) if $config{$self}->{$key}->{DEF};
  0            
235 0 0         $result .= "\n${spaces}Allowed = " . join(", ", @{$config{$self}->{$key}->{ALLOWED}}) if $config{$self}->{$key}->{ALLOWED};
  0            
236 0           $result .= "\n";
237             }
238 0           return $result;
239             }
240              
241             1;
242              
243             __END__