File Coverage

blib/lib/Getopt/Janus/SessionBase.pm
Criterion Covered Total %
statement 170 318 53.4
branch 36 198 18.1
condition 28 107 26.1
subroutine 29 41 70.7
pod 0 30 0.0
total 263 694 37.9


line stmt bran cond sub pod time code
1            
2             require 5;
3             package Getopt::Janus::SessionBase;
4             $VERSION = '1.03';
5 5     5   30 use strict;
  5         10  
  5         183  
6 5     5   703 use Getopt::Janus (); # makes sure Getopt::Janus::DEBUG is defined
  5         10  
  5         135  
7 5     5   1068 BEGIN { *DEBUG = \&Getopt::Janus::DEBUG }
8            
9             # ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
10            
11 0     0 0 0 sub get_option_values { die "ABSTRACTY" } # must override in subclass
12            
13             # ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
14            
15 2     2 0 9 sub string { shift->register_option( 'string' , @_) }
16 2     2 0 23 sub yes_no { shift->register_option( 'yes_no' , @_) }
17 2     2 0 7 sub new_file { shift->register_option( 'new_file', @_) }
18 2     2 0 10 sub file { shift->register_option( 'file' , @_) }
19 4     4 0 13 sub choose { shift->register_option( 'choose' , @_) }
20            
21             # ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
22 0     0 0 0 sub warm_up {''} # can override in subclass
23            
24 2     2 0 6 sub to_run_in_eval {''} # can override in subclass
25            
26 0     0 0 0 sub report_run_error { die 'ABSTRACTY'}
27             # must override in subclass, IF you override to_run_in_eval with a positive value
28            
29             # ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
30 5     5   175 use Carp qw( confess );
  5         11  
  5         357  
31 5     5   5095 use UNIVERSAL ();
  5         73  
  5         17319  
32            
33 2     2 0 6 sub set_title { $_[0]{'title'} = $_[1] }
34 2     2 0 6 sub set_desc { $_[0]{'description'} = $_[1] }
35            
36             # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
37            
38             sub register_option {
39 12     12 0 17 my $self = shift;
40 12         13 my $type = shift;
41 12         15 my $slot = shift;
42 12         25 my($long, $short) = @$self{ 'long', 'short' };
43            
44 12         11 DEBUG > 1 and print "Register_option is hitting $type with options ",
45             map("<$_> ", @_), "\n";
46            
47 12 50       30 confess "Not enough options to $short?!" unless @_;
48            
49 12         11 my($short_count, $long_count);
50 12         29 my $new = { 'type' => $type, 'slot' => $slot };
51            
52 12   66     143 while( @_ and defined $_[0] and !ref($_[0]) and $_[0] =~ m/^-/s ) {
      100        
      100        
53 17         63 my $switch = shift;
54 17 100       91 if($switch =~ s/^-([_0-9a-zA-Z])$/$1/s) {
    50          
55 11         11 DEBUG > 2 and print "Declaring with short switch -$switch\n";
56 11 50 33     35 confess "But there's already a \"-$switch\" switch defined!"
57             if $short->{$switch} and $short->{$switch}{'type'} ne 'HELP';
58 11         557 $short->{$switch} = $new;
59 11         22 $new->{'short'} = $switch;
60 11         83 ++$short_count;
61            
62             } elsif($switch =~ s/^--([-_0-9a-zA-Z]{2,})$/$1/s) {
63 6         6 DEBUG > 2 and print "Declaring with long switch --$switch\n";
64 6 50 33     596 confess "But there's already a \"--$switch\" switch defined!"
65             if $long->{$switch} and $long->{$switch}{'type'} ne 'HELP';
66 6         11 $long->{$switch} = $new;
67 6         12 $new->{'long'} = $switch;
68 6         48 ++$long_count;
69            
70             } else {
71 0         0 confess "Illegal switchname \"$switch\" being declared";
72             }
73             }
74            
75 12 50 66     80 confess "No switchnames specified!?" unless $long_count || $short_count;
76            
77             # string $x, '-x';
78             # string $x, '-x', \'Thingy', k=>v, k=>v,...;
79             # string $x, '-x', \'Thingy', \'This is a thingy', k=>v, k=>v,...;
80            
81 12 100 50     59 if(@_ and ref($_[0] || '') eq 'SCALAR') {
      100        
82 6         7 $new->{'title'} = ${ shift(@_) };
  6         13  
83 6         9 DEBUG > 2 and print "Noting option-title \"$$new{'title'}\"\n";
84            
85 6 100 50     39 if(@_ and ref($_[0] || '') eq 'SCALAR') {
      66        
86 4         4 $new->{'description'} = ${ shift(@_) };
  4         12  
87 4         7 DEBUG > 2 and print "Noting option-desc \"$$new{'description'}\"\n";
88             }
89             }
90            
91 12 50       34 confess "Uneven number of parameter items in call to $type: @_" if @_ % 2;
92            
93 12         28 while( @_ ) {
94 4         8 my($k,$v) = splice(@_,0,2);
95 4 50       10 confess "Can't use undef as an parameter name!" unless defined $k;
96 4 50       9 confess "Can't use empty-string as an parameter name!" unless length $k;
97 4         4 DEBUG > 2 and print "Setting parameter \"$k\" to ",
98             defined($v) ? "\"$v\"" : "(undef)", ".\n";
99 4 50       9 confess "Parameter \"$k\" is already set!" if exists $new->{$k};
100 4         12 $new->{$k} = $v;
101             }
102            
103 12         37 $self->note_new_option( $new );
104            
105 12         13 push @{ $self->{'options'} }, $new;
  12         29  
106            
107 12         33 return;
108             }
109            
110             # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
111            
112             sub note_new_option {
113 12     12 0 16 my($self, $option) = @_;
114 12         25 my $m = 'note_new_option_' . $option->{'type'};
115 12 50       88 $self->$m($option) if $self->can($m);
116 12         19 return;
117             }
118            
119             # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
120            
121             sub prep_options {
122 2     2 0 4 my($self) = @_;
123 2         4 foreach my $o (@{ $self->{'options'} } ) {
  2         6  
124 12         31 $self->prep_option($o);
125             }
126 2         4 return;
127             }
128            
129             # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
130            
131             sub prep_option {
132 12     12 0 16 my($self, $option) = @_;
133 12         27 my $m = 'prep_option_' . $option->{'type'};
134 12 100       101 $self->$m($option) if $self->can($m);
135 12         21 return;
136             }
137            
138             # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
139            
140             sub prep_option_choose {
141 4     4 0 7 my($self, $option) = @_;
142 4   50     13 my $c = ($option->{'from'} ||= ['NONE DEFINED']);
143 4 50       8 return unless @$c; # I guess?
144            
145             # Force it to be one of the choices
146 4         6 for my $val ( ${ $option->{'slot'} } ) { # "for" just to get aliasing
  4         8  
147 4 50       14 if(defined $val) {
    50          
148             # just fall thru to the check
149             } elsif(defined $option->{'default'}) {
150 0         0 $val = $option->{'default'};
151             } else {
152 4         6 $val = $c->[0]; # most common case: set to first.
153             }
154 4 50       17 confess "$val isn't any of the allowed values {@$c}"
155             unless grep $val eq $_, @$c;
156             }
157 4         7 return;
158             }
159            
160 2     2 0 4 sub prep_option_string { } # I can't thing of anything that needs doing.
161            
162             sub prep_option_yes_no {
163 2     2 0 3 my($self, $option) = @_;
164 2         4 for my $val ( ${ $option->{'slot'} } ) { # "for" just to get aliasing
  2         4  
165 2         6 $val = !! $val; # reduce to just boolean
166             }
167 2         4 return;
168             }
169            
170             sub prep_option_new_file {
171 2     2 0 4 my($self, $option) = @_;
172 2         5 for my $slot ( $option->{'slot'} ) { # happy aliasing
173 2 50 33     18 if( defined $$slot and $$slot =~ m/\e/ ) {
174 2         15 $$slot = $self->_new_out( $$slot );
175             }
176 2 50 33     17 if( defined $$slot and length $$slot) {
177 2         4 push @Getopt::Janus::New_files, $slot;
178 2         5 DEBUG and print "Potential new-file: $slot",
179             ref($slot) ? " ($$slot)" : '',
180             "\n from ",
181             $option->{'long'} || $option->{'short'}, ".\n";
182             } else {
183 0         0 DEBUG and print "Snoozing thru new-file option ",
184             $option->{'long'} || $option->{'short'}, ".\n";
185             }
186             }
187 2         4 return;
188             }
189            
190             #==========================================================================
191             sub run {
192 2     2 0 5 my($self, $sub, $title, $desc) = @_;
193            
194 2 50 33     23 confess "first argument to run() should be a subref"
195             unless ref($sub) and UNIVERSAL::isa($sub, 'CODE');
196            
197 2 50 33     18 $title = $$title if $title and ref($title) eq 'SCALAR';
198 2 50 33     74 $desc = $$desc if $desc and ref($desc ) eq 'SCALAR';
199 2   33     19 $self->set_title($title || $0);
200 2 50       15 $self->set_desc($desc) if $desc;
201            
202 2         42 $self->prep_options;
203            
204 2         9 $self->get_option_values;
205            
206 2 50       12 if( $self->to_run_in_eval ) {
207 0         0 DEBUG and print "Running $sub in an eval...\n";
208            
209 0         0 eval { local $SIG{'__DIE__'}; &$sub; };
  0         0  
  0         0  
210            
211 0 0       0 if( $@ ) {
212 0         0 DEBUG and print "That threw an error: $@\n";
213 0         0 $self->report_run_error($@);
214             } else {
215 0         0 DEBUG and print "That didn't throw any errors.\n";
216             }
217             } else {
218 2         2 DEBUG and print "Not running $sub in an eval.\n";
219 2         8 &$sub;
220             }
221            
222 2         2937 DEBUG and print "Starting cleanup.\n";
223 2         21 $self->cleanup();
224 2         2 DEBUG and print "Ending cleanup.\n";
225            
226 2         4 DEBUG and print "Now exiting.\n";
227 2         223 exit;
228             }
229             #==========================================================================
230            
231             sub cleanup {
232 2     2 0 4 my $self = shift;
233 2         11 $self->review_result( \@Getopt::Janus::New_files );
234 2         4 return;
235             }
236            
237             #==========================================================================
238            
239             sub review_result {
240 0     0 0 0 my($self, $them) = @_;
241            
242 0 0       0 unless(@$them) {
243 0         0 DEBUG and print "No files to consider.\n";
244 0         0 return;
245             }
246 0         0 require File::Basename;
247            
248 0         0 if(DEBUG > 1) {
249             print "Contents of new_files:\n";
250             foreach my $i (@$them) {
251             print " [", ref($i) ? "$i = $$i" : $i, "]\n";
252             }
253             }
254            
255 0         0 my(@to_display, %seen, $f_out);
256 0         0 foreach my $f (@$them) {
257 0 0       0 next unless defined $f;
258 0 0       0 $f = $$f if ref $f eq 'SCALAR';
259 0 0 0     0 next unless defined $f and length $f;
260            
261 0         0 DEBUG > 2 and print " Considering [$f]\n";
262            
263 0 0       0 return if $f eq ".NO."; # magic value
264            
265 0 0       0 next if $seen{$f}++; # no repeats
266 0 0       0 unless( -e $f ) {
267 0         0 DEBUG and print " $f doesn't exist\n";
268 0         0 next;
269             }
270 0 0       0 unless( -r _ ) {
271 0         0 DEBUG and print " $f doesn't readable\n";
272 0         0 next;
273             }
274            
275 0 0       0 if(-f _) {
    0          
276 0 0       0 if(-s _) {
277 0         0 DEBUG and print " A good file: $f\n";
278 0         0 $f_out = $f;
279             } else {
280 0         0 DEBUG and print " But it's 0-length: $f\n";
281 0         0 $f_out = undef;
282             }
283 0         0 my $d = File::Basename::dirname( $f );
284 0 0 0     0 $d = '.' if $d eq $f or !length $d;
285 0         0 push @to_display, [$f => $d];
286             } elsif(-d _) {
287 0         0 DEBUG and print " A dir: $f\n";
288 0         0 push @to_display, [undef => $f];
289             } else {
290 0         0 DEBUG and print " Odd, what's a $f ?!\n";
291             }
292             }
293            
294 0         0 if(DEBUG > 1) {
295             print "Contents of to_display: [\n";
296             foreach my $i (@to_display) {
297             print " [", ref($i) ? "$i = $$i" : $i, "]\n";
298             }
299             print "]\n";
300             }
301            
302 0         0 $self->review_result_screen(\@to_display);
303 0         0 return;
304             }
305            
306             sub review_result_screen {
307 0     0 0 0 my($self, $to_display) = @_; # override in a subclass
308 0 0       0 return unless @$to_display;
309 0         0 return;
310             }
311            
312             # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
313            
314 0 0   0 0 0 sub can_open_files { $^O =~ m/Win32/ or $^O =~ m/darwin/ };
315 0 0   0 0 0 sub can_open_directories { $^O =~ m/Win32/ or $^O =~ m/darwin/ };
316            
317             sub open_directory {
318 0     0 0 0 my($self, $i) = @_;
319 0 0 0     0 return $self->open_file($i)
320             if $^O =~ m/Win32/ or $^O =~ m/darwin/;
321 0         0 return;
322             }
323            
324             sub open_file {
325 0     0 0 0 my($self, $i) = @_;
326            
327 0 0       0 if($^O =~ m/darwin/) {
    0          
328             # Thanks to Elaine Ashton and Anno Siegel for help on this
329 0 0 0     0 return unless defined $i and length $i;
330 0         0 DEBUG and print "\nCalling system 'open', $i\n";
331 0         0 sleep 0;
332 0         0 system "open", $i;
333 0         0 sleep 0;
334 0         0 DEBUG and print "\n";
335            
336             } elsif($^O =~ m/Win32/) {
337             # Thanks to Elaine Ashton and Anno Siegel for help on this
338 0 0 0     0 return unless defined $i and length $i;
339 0         0 DEBUG and print "Calling system 'start', qq{\"$i\"}\n";
340 0         0 sleep 0;
341 0         0 system "start", qq{"$i"};
342 0         0 sleep 0;
343 0         0 DEBUG and print "\n";
344             }
345 0         0 return;
346             }
347            
348            
349            
350             #==========================================================================
351            
352             sub new {
353 2     2 0 6 my $class = shift;
354 2   33     15 $class = ref($class) || $class;
355 2         12 my $new = bless { short => {}, long => {}, options => [] }, $class;
356 2         5 DEBUG and print "New $class object.\n";
357 2         12 $new->_init;
358 2         31 return $new;
359             }
360            
361             # can override in a subclass, if you also call $self->SUPER::_init
362             sub _init {
363 2     2   5 my $self = $_[0];
364             $self->{'long' }{'help'} =
365             $self->{'short'}{'h' } =
366             {
367             'type' => 'HELP',
368             'short' => 'h',
369             'long' => 'help',
370 2         3 'slot' => do { my $x; \$x; }, # a dummy slot
  2         4  
  2         23  
371             'title' => "Usage summary / general help",
372             };
373 2         4 return;
374             }
375            
376             #==========================================================================
377            
378             sub _new_out {
379             # Use like: $outname = $self->_new_out("thing\e.txt");
380             # "\e" means "provide an incremented number here"
381 2     2   4 my($self, $in) = @_;
382            
383 2 50 33     16 confess "Can't go on the basis of a null file-specification"
384             unless defined $in and length $in; # sanity
385            
386 2         13 require File::Basename;
387 2         124 my $pattern = File::Basename::basename($in);
388            
389 2         9 my($before, $after) = split "\e", $pattern, 2;
390 2 50       8 $after = '' unless defined $after;
391             {
392             # whip up the pattern:
393 2         4 my $pat_before = quotemeta $before;
  2         5  
394 2         5 my $pat_after = quotemeta $after;
395 2         50 $pattern = qr/^$pat_before(\d+)$pat_after$/is;
396 2         5 DEBUG > 1 and print "Made pattern $pattern from $in\n";
397             }
398            
399             # Look for matching files:
400 2         59 my $dir = File::Basename::dirname($in);
401 2         3 DEBUG > 2 and print "Dirname of [$in] is [$dir]\n";
402 2         4 DEBUG > 1 and print "opendir on $dir for $in\n";
403 2 50       12 $dir = '.' unless defined $dir;
404 2 50       84 opendir(GOODINDIR, $dir) || confess "Can't opendir $dir: $!";
405 2         4 my $max = -1;
406             {
407 2         3 my $this;
  2         2  
408 2         87 while( defined($this = readdir(GOODINDIR)) ) {
409 30 50       127 next unless $this =~ $pattern;
410 0 0       0 if( $1 > $max ) {
411 0         0 $max = 0 + $1;
412 0         0 DEBUG > 5 and print " Hm, $this is highest so far.\n";
413             }
414             }
415             }
416 2         30 closedir(GOODINDIR);
417            
418             # Now make a filename with one greater:
419 2 50       7 if( $max == -1 ) { # none seen
420 2         3 $max = 100; # a good starting number
421             } else {
422 0         0 $max++; # just use one higher than the max
423             }
424 2         6 my $out = $in;
425 2 50       13 $out =~ s/\e/$max/ or $out .= $max;
426 2         3 DEBUG > 1 and print "_better_out returns $out\n";
427 2         9 return $out;
428             }
429            
430             #==========================================================================
431             # Generate the methods for particular licenses:
432            
433             foreach my $licname (qw< artistic gnu either >) {
434             my $sub = sub {
435 2     2   1560 require Getopt::Janus::Licenses;
436 2         6 @{ $_[0] }{ 'license', 'license_short' } = do {
  2         8  
437 5     5   53 no strict 'refs';
  5         19  
  5         552  
438 2         13 *{"Getopt::Janus::Licenses::$licname"}{CODE} ,
  2         9  
439 2         3 *{"Getopt::Janus::Licenses::$licname\_short"}{CODE};
440             };
441 2         6 1;
442             };
443 5     5   30 { no strict 'refs'; *{"license_$licname"} = $sub; }
  5         11  
  5         7481  
444             }
445             # ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
446            
447             sub _help_message {
448 0     0     my($self, $long) = @_;
449 0   0       $long ||= ''; # so it's not undef
450            
451 0   0       my @out = "Options:\n" . ($long && "\n");
452 0 0 0       unshift @out, ( join ' -- ', grep $_,
      0        
453             $self->{'title'}, $self->{'description'}
454             ) . "\n" . ($long && "\n") if $self->{'description'} or $self->{'title'};
455            
456 0           my($type);
457             my %seen;
458 0           foreach my $o (@{ $self->{'options'} } ) {
  0            
459 0 0         my $switch = $o->{'short'} ? ( '-' . $o->{'short'})
    0          
460             : $o->{'long' } ? ('--' . $o->{'long' })
461             : next
462             ;
463 0 0         ++$seen{ $o->{'short'} } if defined $o->{'short'};
464 0 0         ++$seen{ $o->{'long' } } if defined $o->{'long' };
465 0   0       $type = $o->{'type'} || 'No type';
466 0 0         if( $type eq 'yes_no' ) {
    0          
    0          
    0          
    0          
467             # nothing to add
468             } elsif( $type eq 'string' ) {
469 0           $switch .= '=value';
470             } elsif( $type eq 'file' ) {
471 0           $switch .= "=file";
472             } elsif( $type eq 'new_file' ) {
473 0           $switch .= "=new_file";
474             } elsif( $type eq 'choose' ) {
475 0           $switch .= join '' => ( "=option",
476             $long ?
477 0           ( "\n (One of: ", join(q<, >, map qq{"$_"}, @{$o->{'from'}}) )
478 0 0         : ( " (one of: ", join(q<|>, @{$o->{'from'}}) ),
479             ")"
480             );
481             } else {
482 0           $switch .= " [of type $type]"
483             }
484            
485 0 0 0       if($long and $o->{'short'} and $o->{'long'}) {
      0        
486 0 0         $switch =~ s[^(-.(\S*))]
487             [$1 or --$$o{'long'}$2]s
488             or (DEBUG and print "INSANE switch value $switch\n");
489             }
490            
491 0 0 0       push @out, $long ?
      0        
492             ("$switch\n ", $o->{'description'} || $o->{'title'} || '')
493             : ("$switch :: " , $o->{'title'} || $o->{'description'} || ''), "\n" ;
494             }
495 0 0         push @out, "-h :: show a short help message\n" unless $seen{'h'};
496 0 0         push @out, "--help :: show a long help message\n" unless $seen{'help'};
497 0 0         push @out, "\n", $self->{'license_short'}->() if $self->{'license_short'};
498            
499 0           return join '', @out;
500             }
501            
502            
503             # ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
504            
505             sub short_help_message {
506 0     0 0   my($self) = @_;
507            
508 0           my @out = "Options:\n";
509 0 0 0       unshift @out, ( join ' -- ', grep $_,
510             $self->{'title'}, $self->{'description'}
511             ) . "\n" if $self->{'description'} or $self->{'title'};
512            
513 0           my($type);
514             my %seen;
515 0           foreach my $o (@{ $self->{'options'} } ) {
  0            
516 0 0         my $switch = $o->{'short'} ? ( '-' . $o->{'short'})
    0          
517             : $o->{'long' } ? ('--' . $o->{'long' })
518             : next
519             ;
520 0 0         ++$seen{ $o->{'short'} } if defined $o->{'short'};
521 0 0         ++$seen{ $o->{'long' } } if defined $o->{'long' };
522 0   0       $type = $o->{'type'} || 'No type';
523 0 0         if( $type eq 'yes_no' ) {
    0          
    0          
    0          
    0          
524             # nothing to add
525             } elsif( $type eq 'string' ) {
526 0           $switch .= '=value';
527             } elsif( $type eq 'file' ) {
528 0           $switch .= "=file";
529             } elsif( $type eq 'new_file' ) {
530 0           $switch .= "=new_file";
531             } elsif( $type eq 'choose' ) {
532 0           $switch .= "=option (one of: " . join(q<|>, @{$o->{'from'}}) . ")";
  0            
533             } else {
534 0           $switch .= " [of type $type]"
535             }
536 0   0       push @out,
537             "$switch :: ", $o->{'title'} || $o->{'description'} || '', "\n";
538             }
539 0 0         push @out, "-h :: show a short help message\n" unless $seen{'h'};
540 0 0         push @out, "--help :: show a long help message\n" unless $seen{'help'};
541 0 0         push @out, "\n", $self->{'license_short'}->() if $self->{'license_short'};
542            
543 0           return join '', @out;
544             }
545            
546             # ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
547            
548             sub long_help_message {
549 0     0 0   my($self) = @_;
550            
551 0           my @out = "Options:\n\n";
552 0 0 0       unshift @out, ( join ' -- ', grep $_,
553             $self->{'title'}, $self->{'description'}
554             ) . "\n\n" if $self->{'description'} or $self->{'title'};
555 0           my($type);
556             my %seen;
557 0           foreach my $o (@{ $self->{'options'} } ) {
  0            
558 0 0         my $switch = $o->{'short'} ? ( '-' . $o->{'short'})
    0          
559             : $o->{'long' } ? ('--' . $o->{'long' })
560             : next
561             ;
562 0 0         ++$seen{ $o->{'short'} } if defined $o->{'short'};
563 0 0         ++$seen{ $o->{'long' } } if defined $o->{'long' };
564 0   0       $type = $o->{'type'} || 'No type';
565 0 0         if( $type eq 'yes_no' ) {
    0          
    0          
    0          
    0          
566             # nothing to add
567             } elsif( $type eq 'string' ) {
568 0           $switch .= '=value';
569             } elsif( $type eq 'file' ) {
570 0           $switch .= "=file";
571             } elsif( $type eq 'new_file' ) {
572 0           $switch .= "=new_file";
573             } elsif( $type eq 'choose' ) {
574 0           $switch .= "=option\n (One of: " .
575 0           join(q<, >, map qq{"$_"}, @{$o->{'from'}}) . ")";
576             } else {
577 0           $switch .= " [of type $type]"
578             }
579            
580 0 0 0       if($o->{'short'} and $o->{'long'}) {
581 0 0         $switch =~ s/^(-.(\S*))/$1 or --$$o{'long'}$2/s or print "WHAT $switch";
582             }
583 0   0       push @out,
584             "$switch\n ", $o->{'description'} || $o->{'title'} || '', "\n";
585             }
586 0 0         push @out, "-h :: show a short help message\n" unless $seen{'h'};
587 0 0         push @out, "--help :: show a long help message\n" unless $seen{'help'};
588 0 0         push @out, "\n", $self->{'license_short'}->() if $self->{'license_short'};
589            
590 0           return join '', @out;
591             }
592            
593             # ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
594            
595             1;
596             __END__