File Coverage

blib/lib/Getopt/Euclid.pm
Criterion Covered Total %
statement 617 655 94.2
branch 231 274 84.3
condition 61 80 76.2
subroutine 60 62 96.7
pod 7 7 100.0
total 976 1078 90.5


line stmt bran cond sub pod time code
1             package Getopt::Euclid;
2              
3 65     65   292127 use version; our $VERSION = version->declare('0.4.5');
  65         126479  
  65         396  
4              
5 65     65   6000 use warnings;
  65         138  
  65         1667  
6 65     65   347 use strict;
  65         133  
  65         1140  
7 65     65   1145 use 5.005000; # perl 5.5.0
  65         454  
8 65     65   361 use Carp;
  65         134  
  65         5355  
9 65     65   30724 use Symbol ();
  65         52594  
  65         2074  
10 65     65   425 use re 'eval'; # for matcher regex
  65         128  
  65         4077  
11 65     65   34678 use Pod::Select;
  65         129351  
  65         7432  
12 65     65   34287 use Pod::PlainText;
  65         274721  
  65         3752  
13 65     65   528 use File::Basename;
  65         140  
  65         7305  
14 65     65   28352 use File::Spec::Functions qw(splitpath catpath catfile);
  65         54359  
  65         5038  
15 65     65   482 use List::Util qw( first );
  65         148  
  65         7703  
16 65     65   46540 use Text::Balanced qw(extract_multiple extract_bracketed extract_variable extract_delimited);
  65         1125791  
  65         160960  
17              
18              
19             # Set some module variables
20             my $skip_keyword = 'Getopt::Euclid'; # Ignore files with a first line containing this keyword.
21             my $pod_file_msg = "# This file was generated dynamically by $skip_keyword. Do not edit it.";
22              
23             my $has_run = 0;
24             my $has_processed_pod = 0;
25             my $export_lvl = 1;
26             my @pod_names;
27             my $minimal_keys;
28             my $vars_prefix;
29             my $defer = 0;
30             my $matcher;
31             my %requireds;
32             my %options;
33             my %longnames;
34             our $man; # --man message
35             my $help; # --help message
36             my $usage; # --usage message
37             my $version; # --version message
38              
39             my $optional_re;
40             $optional_re = qr{ \[ [^[]* (?: (??{$optional_re}) [^[]* )* \] }xms;
41              
42              
43             # Global variables
44             our $SCRIPT_NAME;
45             our $SCRIPT_VERSION; # for ticket # 55259
46              
47              
48             # Convert arg specification syntax to Perl regex syntax
49              
50             my %std_matcher_for = (
51             integer => '[+-]?\\d+(?:[eE][+]?\d+)?',
52             number => '[+-]?(?:\\d+\\.?\\d*|\\.\\d+)(?:[eE][+-]?\d+)?',
53             input => '\S+',
54             output => '\S+',
55             string => '\S+',
56             q{} => '\S+',
57             );
58              
59             _make_equivalent(
60             \%std_matcher_for,
61             integer => [qw( int i +int +i 0+int 0+i +integer 0+integer )],
62             number => [qw( num n +num +n 0+num 0+n +number 0+number )],
63             input => [qw( readable in )],
64             output => [qw( writable writeable out )],
65             string => [qw( str s )],
66             );
67              
68             my %std_constraint_for = (
69             'string' => sub { 1 }, # Always okay (matcher ensures this)
70             'integer' => sub { 1 }, # Always okay (matcher ensures this)
71             '+integer' => sub { $_[0] > 0 },
72             '0+integer' => sub { $_[0] >= 0 },
73             'number' => sub { 1 }, # Always okay (matcher ensures this)
74             '+number' => sub { $_[0] > 0 },
75             '0+number' => sub { $_[0] >= 0 },
76             'input' => sub { $_[0] eq '-' || -r $_[0] },
77             'output' => sub {
78             my ( $vol, $dir ) = splitpath( $_[0] );
79             $dir = ($vol && $dir) ? catpath($vol, $dir) : '.';
80             $_[0] eq '-' ? 1 : -e $_[0] ? -w $_[0] : -w $dir;
81             },
82             );
83              
84             _make_equivalent(
85             \%std_constraint_for,
86             'integer' => [qw( int i )],
87             '+integer' => [qw( +int +i )],
88             '0+integer' => [qw( 0+int 0+i )],
89             'number' => [qw( num n )],
90             '+number' => [qw( +num +n )],
91             '0+number' => [qw( 0+num 0+n )],
92             'string' => [qw( str s )],
93             'input' => [qw( in readable )],
94             'output' => [qw( out writable writeable )],
95             );
96              
97              
98             sub Getopt::Euclid::Importer::DESTROY {
99 0 0 0 0   0 return if $has_run || $^C; # No errors when only compiling
100 0         0 croak '.pm file cannot define an explicit import() when using Getopt::Euclid';
101             }
102              
103              
104             sub import {
105 69     69   1983 shift @_;
106 69   100     199 @_ = grep { !( /:minimal_keys/ and $minimal_keys = 1 ) } @_;
  11         110  
107 69   66     135 @_ = grep { !( /:vars(?:<(\w+)>)?/ and $vars_prefix = $1 || 'ARGV_' ) } @_;
  6         51  
108 69   100     134 @_ = grep { !( /:defer/ and $defer = 1 ) } @_;
  4         29  
109 69         375 croak "Unknown mode ('$_')" for @_;
110 68 100       275 $export_lvl++ if not $defer;
111              
112             # No POD parsing and argument processing in Perl compile mode (ticket 34195)
113 68 100       338 return if $^C;
114              
115             # Get name of caller program and its modules in @pod_names
116 67 100       166 return unless _get_pod_names();
117              
118             # Extract POD of given files
119 63         335 __PACKAGE__->process_pods( [reverse @pod_names] );
120 63         184 undef @pod_names;
121 63         113 $has_run = 1;
122              
123             # Parse POD + parse and export arguments
124              
125             ######
126             #use Data::Dumper; print "ARGV: ".Dumper(\@ARGV);
127             ######
128              
129 63 100       454 __PACKAGE__->process_args( \@ARGV ) unless $defer;
130              
131 36         5023 return 1;
132             }
133              
134              
135             sub process_pods {
136             # Extract POD content from list of Perl scripts (.pl) and modules (.pm) and
137             # their corresponding .pod file if available. When given the argument
138             # {-strict => 1}, do not look for .pod files.
139 64     64 1 2294 my ($self, $perl_files, $args) = @_;
140              
141 64         116 my $pod_string = '';
142 35 50   35   18718 open my $pod_fh, '>', \$pod_string
  35         465  
  35         206  
  64         1931  
143             or croak "Could not open filehandle to variable because $!";
144 64         25809 for my $perl_file (@$perl_files) {
145              
146 67         121 my $got_pod_file = 0;
147              
148 67 50       239 if ( not $args->{-strict} ) {
149              
150             # Find corresponding .pod file
151 67         5967 my ($name_re, $path, $suffix) = fileparse($perl_file, qr/\.[^.]*/);
152 67         758 my $pod_file = catfile( $path, $name_re.'.pod' );
153              
154             # Get POD either from .pod file (preferably) or from Perl file
155 67 100       2647 if ( -e $pod_file ) {
156             # Get .pod file content
157 6 50       244 open my $in, '<', $pod_file
158             or croak "Could not open file $pod_file because $!";
159 6         159 my $first_line = <$in>;
160 6         28 chomp $first_line;
161 6 100       92 if ( not ($first_line =~ m/$skip_keyword/) ) {
162             # Skip G::E auto-generated files since they lack important data
163 4         26 print $pod_fh "$first_line\n";
164 4         178 print $pod_fh $_ while <$in>;
165 4         14 $got_pod_file = 1;
166             }
167 6         87 close $in;
168             }
169             }
170              
171 67 100       273 if (not $got_pod_file) {
172             # Parse POD content of Perl file
173 63         409 podselect( {-output => $pod_fh}, $perl_file );
174             }
175 67 100       175180 print $pod_fh "\n" if $pod_string;
176              
177             }
178 64         215 close $pod_fh;
179 64         181 $man = $pod_string;
180 64         233 return 1;
181             }
182              
183              
184             sub process_args {
185             # First, parse the POD specifications. Then, parse the given array of
186             # arguments (\@ARGV or other) and populate %ARGV (or export specific
187             # variable names).
188 70     70 1 46955 my ($self, $args, $options) = @_;
189              
190             # Parse POD
191 70 100       225 if (not $has_processed_pod) {
192 64         214 _parse_pod();
193 51         112 $has_processed_pod = 1;
194             }
195              
196             # Set options for argument parsing
197 57 100       217 if (defined $options) {
198 2 100       10 if (exists $options->{-minimal_keys}) {
199 1         3 $minimal_keys = 1;
200             }
201 2 100       9 if (exists $options->{-vars}) {
202 1         3 $vars_prefix = $options->{-vars};
203             }
204             }
205              
206 57         173 %ARGV = ();
207              
208             # Handle standard args...
209 57 50   629   688 if ( first { $_ eq '--man' } @$args ) {
  629 50       1127  
    50          
    50          
    50          
210 0         0 _print_pod( __PACKAGE__->man(), 'paged' );
211 0         0 exit;
212 629     629   960 } elsif ( first { $_ eq '--usage' } @$args ) {
213 0         0 print __PACKAGE__->usage();
214 0         0 exit;
215 629     629   1130 } elsif ( first { $_ eq '--help' } @$args ) {
216 0         0 _print_pod( __PACKAGE__->help(), 'paged' );
217 0         0 exit;
218 629     629   1066 } elsif ( first { $_ eq '--version' } @$args ) {
219 0         0 print __PACKAGE__->version();
220 0         0 exit;
221 629     629   856 } elsif ( first { $_ eq '--podfile' } @$args ) {
222             # Option meant for authors
223 0         0 my $podfile = podfile( );
224 0         0 print "Wrote POD manual in file $podfile\n";
225 0         0 exit;
226             }
227              
228             # Subroutine to report problems during parsing...
229             *_bad_arglist = sub {
230 16     16   51 my (@msg) = @_;
231 16         55 my $msg = join q{}, @msg;
232 16         46 $msg = _rectify_arg($msg);
233 16         111 $msg =~ s/\n?\z/\n/xms;
234 16         231 warn "$msg\nTry this for usage help: $SCRIPT_NAME --help\n".
235             "Or this for full manual: $SCRIPT_NAME --man\n\n";
236 16         94 exit 2; # Traditional "bad arg list" value
237 57         860 };
238              
239             # Run matcher...
240 57         181 my $argv = join( q{ }, map { $_ = _escape_arg($_) } @$args );
  629         1011  
241 57         467 my $all_args_ref = { %options, %requireds };
242 57 100       276 if ( my $error = _doesnt_match( $matcher, $argv, $all_args_ref ) ) {
243 7         39 _bad_arglist($error);
244             }
245              
246             # Check that all requireds have been found...
247 50         123 my @missing;
248 50         258 while ( my ($req) = each %requireds ) {
249 101 100       595 push @missing, "\t$req\n" if !exists $ARGV{$req};
250             }
251             _bad_arglist(
252 50 50       196 'Missing required argument',
    100          
253             ( @missing == 1 ? q{} : q{s} ),
254             ":\n", @missing
255             ) if @missing;
256              
257             # Back-translate \0-quoted spaces and \1-quoted tabs...
258 49         191 _rectify_all_args();
259              
260             # Check exclusive variables, variable constraints and fill in defaults...
261 49         418 _verify_args($all_args_ref);
262              
263             # Clean up @$args since everything must have been parsed
264 41         140 @$args = ();
265              
266             # Clean up %ARGV
267 41         140 for my $arg_name ( keys %ARGV ) {
268              
269             # Flatten non-repeatables...
270 260         557 my $vals = delete $ARGV{$arg_name};
271 260         514 my $repeatable = $all_args_ref->{$arg_name}{is_repeatable};
272 260 100       526 if ($repeatable) {
273 4         5 pop @{$vals};
  4         6  
274             }
275              
276 260         366 for my $val ( @{$vals} ) {
  260         500  
277 260         335 my $var_count = keys %{$val};
  260         417  
278             $val = $var_count == 0
279             ? 1 # Boolean -> true
280             : $var_count == 1
281 260 100       704 ? ( values %{$val} )[0] # Single var -> var's val
  214 50       503  
282             : $val # Otherwise keep hash
283             ;
284 260         573 my $false_vals = $all_args_ref->{$arg_name}{false_vals};
285 260         351 my %vars_opt_vals;
286              
287 260         523 for my $arg_flag ( _get_variants($arg_name) ) {
288 480         729 my $variant_val = $val;
289 480 100 100     1298 if ( $false_vals && $arg_flag =~ m{\A $false_vals \z}xms ) {
290 14 100       38 $variant_val = $variant_val ? 0 : 1;
291             }
292              
293 480 100       855 if ($repeatable) {
294 25         29 push @{ $ARGV{$arg_flag} }, $variant_val;
  25         55  
295             } else {
296 455         902 $ARGV{$arg_flag} = $variant_val;
297             }
298 480 100       1016 $vars_opt_vals{$arg_flag} = $ARGV{$arg_flag} if $vars_prefix;
299             }
300              
301 260 100       813 if ($vars_prefix) {
302 28         87 _minimize_entries_of( \%vars_opt_vals );
303 28         69 my $maximal = _longestname( keys %vars_opt_vals );
304 28         86 _export_var( $vars_prefix, $maximal, $vars_opt_vals{$maximal} );
305 28         105 delete $longnames{$maximal};
306             }
307             }
308             }
309              
310 41 100       223 if ($vars_prefix) {
311              
312             # Export any unspecified options to keep use strict happy
313 3         16 while ( my ($opt_name, $arg_name) = each %longnames ) {
314 17         33 my $arg_info = $all_args_ref->{$arg_name};
315 17         24 my $val;
316 17 100 100     66 if ( $arg_info->{is_repeatable} or $arg_name =~ />\.\.\./ ) {
317             # Empty arrayref for repeatable options
318 3         4 $val = [];
319             } else {
320 14 100       20 if (keys %{ $arg_info->{var} } > 1) {
  14         38  
321             # Empty hashref for non-repeatable options with multiple placeholders
322 1         3 $val = {};
323             }
324             }
325 17         51 _export_var( $vars_prefix, $opt_name, $val );
326             }
327             }
328              
329              
330 41 100       134 if ($minimal_keys) {
331 6         23 _minimize_entries_of( \%ARGV );
332             }
333              
334 41         168 return 1;
335             }
336              
337              
338             sub podfile {
339             # Write the given POD doc into a .pod file, overwriting any existing .pod file
340 1 50   1 1 1478 return if not -e $0;
341 1         58 my ($name_re, $path, $suffix) = fileparse($0, qr/\.[^.]*/);
342 1         11 my $pod_file = catfile( $path, $name_re.'.pod' );
343 1 50       145 open my $out_fh, '>', $pod_file or croak "Could not write file $pod_file because $!";
344 1         11 print $out_fh $pod_file_msg."\n\n".__PACKAGE__->man();
345 1         56 close $out_fh;
346 1         10 return $pod_file;
347             }
348              
349              
350             sub man {
351 6     6 1 21370 return $man;
352             }
353              
354              
355             sub usage {
356 1     1 1 681 return $usage;
357             }
358              
359              
360             sub help {
361 2     2 1 1567 return $help;
362             }
363              
364              
365             sub version {
366 1     1 1 643 return $version;
367             }
368              
369              
370             # # # # # # # # Utility subs # # # # # # # #
371              
372             # Recursively remove decorations on %ARGV keys
373              
374             sub AUTOLOAD {
375 9     9   19 our $AUTOLOAD;
376 9         50 $AUTOLOAD =~ s{.*::}{main::}xms;
377 65     65   635 no strict 'refs';
  65         180  
  65         455354  
378 9         66 goto &$AUTOLOAD;
379             }
380              
381              
382             sub _parse_pod {
383             # Set up parsing rules...
384 64     64   268 my $space_re = qr{ [^\S\n]* }xms;
385 64         210 my $head_start_re = qr{ ^=head1 }xms;
386 64         1344 my $head_end_re = qr{ (?= $head_start_re | \z) }xms;
387 64         296 my $pod_cmd_re = qr{ = [^\W\d]\w+ [^\n]* (?= \n\n )}xms;
388 64         1556 my $pod_cut_re = qr{ (?! \n\n ) = cut $space_re (?= \n\n )}xms;
389              
390 64         2254 my $name_re = qr{ $space_re NAME $space_re \n }xms;
391 64         2295 my $vers_re = qr{ $space_re VERSION $space_re \n }xms;
392 64         2097 my $usage_re = qr{ $space_re USAGE $space_re \n }xms;
393              
394 64         333 my $std_re = qr{ STANDARD | STD | PROGRAM | SCRIPT | CLI | COMMAND(?:-|\s)?LINE }xms;
395 64         2576 my $arg_re = qr{ $space_re (?:PARAM(?:ETER)?|ARG(?:UMENT)?)S? }xms;
396              
397 64         6572 my $options_re = qr{ $space_re $std_re? $space_re OPTION(?:AL|S)? $arg_re? $space_re \n }xms;
398 64         6708 my $required_re = qr{ $space_re $std_re? $space_re (?:REQUIRED|MANDATORY) $arg_re? $space_re \n }xms;
399              
400 64         427 my $euclid_arg = qr{ ^=item \s* ([^\n]*?) \s* \n\s*\n
401             (
402             .*?
403             (?:
404             ^=for \s* (?i: Euclid) .*? \n\s*\n
405             | (?= ^=[^\W\d]\w* | \z)
406             )
407             )
408             }xms;
409              
410             # Clean up line delimiters
411 64         2348 $man =~ s{ [\n\r] }{\n}gx;
412              
413             # Clean up significant entities...
414 64         260 $man =~ s{ E }{<}gxms;
415 64         167 $man =~ s{ E }{>}gxms;
416              
417             # Put program name in man
418 64 100       1507 $SCRIPT_NAME = (-e $0) ? (splitpath $0)[-1] : 'one-liner';
419 64 100       5089 $man =~ s{ ($head_start_re $name_re \s*) .*? (- .*)? $head_end_re }
  52         1306  
420             {$1.$SCRIPT_NAME.($2 ? " $2" : "\n\n")}xems;
421              
422 64         3700 # Put version number in man
423             ($SCRIPT_VERSION) =
424 64 100       414 $man =~ m/$head_start_re $vers_re .*? (\d+(?:[._]\d+)+) .*? $head_end_re /xms;
425 14         56 if ( !defined $SCRIPT_VERSION ) {
426             $SCRIPT_VERSION = $main::VERSION;
427 64 100       324 }
428 14 100       1050 if ( !defined $SCRIPT_VERSION ) {
429             $SCRIPT_VERSION = (-e $0) ? localtime((stat $0)[9]) : 'one-liner';
430 64         3837 }
431             $man =~ s{ ($head_start_re $vers_re \s*) .*? (\s*) $head_end_re }
432             {$1This document refers to $SCRIPT_NAME version $SCRIPT_VERSION $2}xms;
433 64         258  
434 64         8578 # Extra info from PODs
435             my ($options, $opt_name, $required, $req_name, $licence);
436 51         359 while ($man =~ m/$head_start_re ($required_re) (.*?) $head_end_re /gxms) {
437 51 50       218 # Required arguments
438 51   50     1045 my ( $more_req_name, $more_required ) = ($1, $2);
      50        
439             $req_name = $more_req_name if not defined $req_name;
440 64         9707 $required = ( $more_required || q{} ) . ( $required || q{} );
441             }
442 55         429 while ($man =~ m/$head_start_re ($options_re) (.*?) $head_end_re /gxms) {
443 55 50       233 # Optional arguments
444 55   50     1011 my ( $more_opt_name, $more_options ) = ($1, $2);
      50        
445             $opt_name = $more_opt_name if not defined $opt_name;
446 64         6608 $options = ( $more_options || q{} ) . ( $options || q{} );
447             }
448 47         265 while ($man =~ m/$head_start_re [^\n]+ (?i: licen[sc]e | copyright ) .*? \n \s* (.*?) \s* $head_end_re /gxms) {
449 47   50     552 # License information
      50        
450             my ($more_licence) = ($1, $2);
451             $licence = ( $more_licence || q{} ) . ( $licence || q{} );
452             }
453 64         222  
454 128 100       416 # Clean up interface titles...
455 106         699 for my $name_re ( $opt_name, $req_name ) {
456             next if !defined $name_re;
457             $name_re =~ s{\A \s+ | \s+ \z}{}gxms;
458             }
459 64         153  
460 64         150 # Extract the actual interface and store each arg entry into a hash of specifications...
461 64   100     6187 my $seq = 0;
462 120         487 my $seen = {};
463 120         1420 while ( ( $required || q{} ) =~ m{ $euclid_arg }gxms ) {
464             $seen = _register_specs( $1, $2, $seq, \%requireds, \%longnames, $seen );
465 64   100     5960 $seq++;
466 418         1189 }
467 417         4903 while ( ( $options || q{} ) =~ m{ $euclid_arg }gxms ) {
468             $seen = _register_specs( $1, $2, $seq, \%options, \%longnames, $seen );
469 63         253 $seq++;
470 63         265 }
471             undef $seen;
472             _minimize_entries_of( \%longnames );
473 63         440  
474 63         269 # Extract Euclid information...
475             my $all_specs = {%requireds, %options};
476             _process_euclid_specs( $all_specs );
477 52         182  
478 51         163 # Insert default values (if any) in the program's documentation
479             $required = _insert_default_values(\%requireds);
480             $options = _insert_default_values(\%options );
481              
482 51         266 # One-line representation of interface...
  140         346  
483             my $arg_summary = join ' ', (sort
484             { $requireds{$a}{'seq'} <=> $requireds{$b}{'seq'} }
485 51         511 (keys %requireds));
486              
487 51 100       205 1 while $arg_summary =~ s/\[ [^][]* \]//gxms;
488 42 100       187  
489 42         155 if ($opt_name) {
490             $arg_summary .= ' ' if $arg_summary;
491 51         327 $arg_summary .= lc "[$opt_name]";
492             }
493             $arg_summary =~ s/\s+/ /gxms;
494 51         3652  
495 51         8594 # Manual message
496 51         10197 $man =~ s{ ($head_start_re $usage_re \s*) .*? (\s*) $head_end_re } {$1$SCRIPT_NAME $arg_summary$2}xms;
497             $man =~ s{ ($head_start_re $required_re \s*) .*? (\s*) $head_end_re } {$1$required$2}xms;
498             $man =~ s{ ($head_start_re $options_re \s*) .*? (\s*) $head_end_re } {$1$options$2}xms;
499 51         312  
500 51         163 # Usage message
501 51         163 $usage = " $SCRIPT_NAME $arg_summary\n";
502 51         133 $usage .= " $SCRIPT_NAME --help\n";
503 51         140 $usage .= " $SCRIPT_NAME --man\n";
504             $usage .= " $SCRIPT_NAME --usage\n";
505             $usage .= " $SCRIPT_NAME --version\n";
506 51         299  
507 51 100 100     610 # Help message
508             $help = "=head1 \L\uUsage:\E\n\n$usage\n";
509 51 100 100     609 $help .= "=head1 \L\u$req_name:\E\n\n$required\n\n"
510             if ( $req_name || q{} ) =~ /\S/;
511             $help .= "=head1 \L\u$opt_name:\E\n\n$options\n\n"
512 51         189 if ( $opt_name || q{} ) =~ /\S/;
513              
514             $usage = "Usage:\n".$usage;
515 51         191  
516 51 100       296 # Version message
517             $version = "This is $SCRIPT_NAME version $SCRIPT_VERSION\n";
518             $version .= "\n$licence\n" if $licence;
519 51         335  
520             # Convert arg specifications to regexes...
521             _convert_to_regex( $all_specs );
522 51         220  
523 435         1464 # Build matcher...
524 1017         1591 my @arg_list = ( values(%requireds), values(%options) );
  435         1117  
525 51         157 $matcher = join '|', map { $_->{matcher} }
  1         4  
  435         850  
526 51         323 sort( { $b->{name} cmp $a->{name} } grep { $_->{name} =~ /^[^<]/ } @arg_list ),
527 51         461 sort( { $a->{seq} <=> $b->{seq} } grep { $_->{name} =~ /^[<]/ } @arg_list );
528             $matcher .= '|(?> (.+)) (?{ push @errors, $^N }) (?!)';
529 51         639 $matcher = '(?:' . $matcher . ')';
530              
531             return 1;
532             }
533              
534 538     538   2094  
535 538         1122 sub _register_specs {
536 538         2664 my ($name_re, $spec, $seq, $storage, $longnames, $seen) = @_;
537             my @variants = _get_variants($name_re);
538             $storage->{$name_re} = {
539             seq => $seq,
540             src => $spec,
541             name => $name_re,
542 538 100       1314 variants => \@variants,
543 41         85 };
544             if ($minimal_keys) {
545             my $minimal = _minimize_name($name_re);
546 41 100       349 croak "Internal error: minimalist mode caused arguments ".
547 40         87 "'$name_re' and '".$seen->{$minimal}."' to clash"
548             if $seen->{$minimal};
549 537         1143 $seen->{$minimal} = $name_re;
550 537         1452 }
551             $longnames->{ _longestname(@variants) } = $name_re;
552             return $seen;
553             }
554              
555 63     63   188  
556 63         137 sub _process_euclid_specs {
557             my ($args) = @_;
558             my %all_var_list;
559             my %excluded_by_def;
560 63         398  
561             ARG:
562             while ( (undef, my $arg) = each %$args ) {
563 488         1224  
564 486         1780 # Validate and record variable names seen here...
565 378         1268 my $var_list = _validate_name( $arg->{name} );
566             while (my ($var_name, undef) = each %$var_list) {
567             $all_var_list{$var_name} = undef;
568             }
569 486 100       3325  
570             # Process arguments with a Euclid specification further
571 238         677 $arg->{src} =~ s{^ =for \s+ Euclid\b [^\n]* \s* (.*) \z}{}ixms
572             or next ARG;
573 238         669 my $info = $1;
574              
575 238         391 $arg->{is_repeatable} = $info =~ s{^ \s* repeatable \s*? $}{}xms;
576 238         671  
577 10         25 my @false_vals;
578 10         69 while ( $info =~ s{^ \s* false \s*[:=] \s* ([^\n]*)}{}xms ) {
579 10         20 my $regex = $1;
  0         0  
580 10         32 1 while $regex =~ s/ \[ ([^]]*) \] /(?:$1)?/gxms;
581             $regex =~ s/ (\s+) /$1.'[\\s\\0\\1]*'/egxms;
582 238 100       550 push @false_vals, $regex;
583 8         33 }
584             if (@false_vals) {
585             $arg->{false_vals} = '(?:' . join( '|', @false_vals ) . ')';
586 238         1278 }
587              
588             while (
589 403         1793 $info =~ m{\G \s* (([^.]+)\.([^:=\s]+) \s*[:=]\s* ([^\n]*)) }gcxms )
590             {
591             my ( $spec, $var, $field, $val ) = ( $1, $2, $3, $4 );
592 403 100       4198  
593 1         8 # Check for misplaced fields...
594             if ( $arg->{name} !~ m{\Q<$var>}xms ) {
595             _fail( "Invalid constraint: $spec\n(No <$var> placeholder in ".
596             "argument: $arg->{name})" );
597             }
598 402 100 100     1652  
    100          
    100          
    100          
    100          
599 2         10 # Decode...
600             if ( $field eq 'type.error' ) {
601 238         616 $arg->{var}{$var}{type_error} = $val;
602 238         1298 } elsif ( $field eq 'type' ) {
603             $val = _qualify_variables_fully( $val );
604 238         911 my ( $matchtype, $comma, $constraint ) =
605 238 100 66     1042 $val =~ m{(/(?:\.|.)+/ | [^,\s]+)\s*(?:(,))?\s*(.*)}xms;
    100          
606 18         384 $arg->{var}{$var}{type} = $matchtype;
607             if ( $comma && length $constraint ) {
608 18         217 ( $arg->{var}{$var}{constraint_desc} = $constraint ) =~
609 18 50       2076 s/\s*\b\Q$var\E\b\s*//g;
610             $constraint =~ s/\b\Q$var\E\b/\$_[0]/g;
611             $arg->{var}{$var}{constraint} = eval "sub{ $constraint }"
612 38         129 or _fail("Invalid .type constraint: $spec\n($@)");
613             } elsif ( length $constraint ) {
614 38 50       3351 $arg->{var}{$var}{constraint_desc} = $constraint;
615             $arg->{var}{$var}{constraint} =
616             eval "sub{ \$_[0] $constraint }"
617 182         436 or _fail("Invalid .type constraint: $spec\n($@)");
618             } else {
619             $arg->{var}{$var}{constraint_desc} = $matchtype;
620 4     4   13 $arg->{var}{$var}{constraint} =
621 182 100       1383 $matchtype =~ m{\A\s*/.*/\s*\z}xms
    100          
622             ? sub { 1 }
623             : $std_constraint_for{$matchtype}
624             or _fail("Unknown .type constraint: $spec");
625             }
626 154         352  
627 154 100       10137 } elsif ( ($field eq 'default') || ($field eq 'opt_default') ) {
628             $val = _qualify_variables_fully( $val );
629 153         706 eval "\$val = $val; 1"
630 153         370 or _fail("Invalid .$field value: $spec\n($@)");
631             $arg->{var}{$var}{$field} = $val;
632 153 100       504 my $has_field = 'has_'.$field;
633             $arg->{$has_field} = exists $arg->{$has_field} ?
634             $arg->{$has_field}++ :
635 153 100       627 1;
636              
637 7 100       28 if ($field eq 'opt_default') {
638 1         7 # Check that placeholders with optional defaults have a flagged argument
639             if ( $arg->{name} =~ m{^<}xms ) {
640             _fail( "Invalid .$field constraint: $spec\nParameter ".
641             "$arg->{name} must have a flag" );
642 6 100       90 }
643 1         7 # Check that placeholders with optional defaults is optional
644             if ( $arg->{name} !~ m{\Q[<$var>]}xms ) {
645             _fail( "Invalid .$field constraint: $spec\nPlaceholder".
646             " <$var> must be optional, i.e. [<$var>], to have ".
647             "an optional default in argument: $arg->{name}" );
648             }
649             }
650 1         4  
651             } elsif ( $field eq 'excludes.error' ) {
652 6         32 $arg->{var}{$var}{excludes_error} = $val;
653 6         13 } elsif ( $field eq 'excludes' ) {
  6         22  
654 8 100       41 $arg->{var}{$var}{excludes} = [ split '\s*,\s*', $val ];
655 1         5 for my $excl_var (@{$arg->{var}{$var}{excludes}}) {
656             if ($var eq $excl_var) {
657             _fail( "Invalid .excludes value for variable <$var>: ".
658             "<$excl_var> cannot exclude itself." );
659             }
660 1         5 }
661             } else {
662             _fail("Unknown specification: $spec");
663             }
664 231         395 }
  487         1745  
665 256         370 # Record variables excluded by another that has a default
  256         868  
666 7 100       26 while (my ($var_name, $var_data) = each %{$arg->{var}}) {
667 7 50       22 for my $excl_var (@{$arg->{var}{$var_name}{excludes}}) {
668             $excluded_by_def{$excl_var}{default}{$var_name} = 1 if $arg->{has_default};
669             $excluded_by_def{$excl_var}{opt_default}{$var_name} = 1 if $arg->{has_opt_default};
670 231 100       1619 }
671 1         6 }
672             if ( $info =~ m{\G \s* ([^\s\0\1] [^\n]*) }gcxms ) {
673             _fail("Unknown specification: $1");
674             }
675             }
676              
677 53         288 # Validate and complete .excludes specs
678 448         600  
  690         2079  
679             while ( (undef, my $arg) = each %$args ) {
680 243         340 while ( my ($var, $var_specs) = each %{$arg->{var}} ) {
  243         462  
681 7 100       18 # Check for invalid placeholder name in .excludes specifications
682 1         5 for my $excl_var (@{$var_specs->{excludes}}) {
683             if (not exists $all_var_list{$excl_var}) {
684             _fail( "Invalid .excludes value for variable <$var>: ".
685             "<$excl_var> does not exist\n" );
686             }
687 242         380 }
688 484 100 100     1410 # Remove default for placeholders excluded by others that have a default
689 3         6 for my $type ( 'default', 'opt_default' ) {
690 3         8 if ( (exists $arg->{var}->{$var}->{$type}) && (exists $excluded_by_def{$var}{$type}) ) {
691 3 100       9 delete $arg->{var}->{$var}->{$type};
692 2         7 $arg->{"has_$type"}--;
693             if ($arg->{"has_$type"} == 0) {
694             delete $arg->{"has_$type"};
695             }
696             }
697             }
698             }
699 52         185 }
700              
701             return 1;
702             }
703              
704              
705             sub _qualify_variables_fully {
706             # Restore fully-qualified name to variables:
707             # $x becomes $main::x
708             # $::x becomes $main::x
709             # $Package::x stays as $Package::x
710             # /^asdf$/ stays as /^asdf$/
711 392     392   827 # '$10' stays as '$10'
712 392 100       1073 # Note: perlvar indicates that ' can also be used instead of ::
713 9         14 my ($val) = @_;
714 9     294   57 if ($val =~ m/[\$\@\%]/) { # Avoid expensive Text::Balanced operations when there are no variables
  294         20113  
715 10 100       705 my $new_val;
716             for my $s (extract_multiple($val,[{Quoted=>sub{extract_delimited($_[0])}}],undef,0)) {
717 9         16 if (not ref $s) {
  9         24  
718             # A non-quoted section... may contain variables to fix
719 11 100       37 for my $var_name ( @{_get_variable_names($s)} ) {
720             # Skip fully qualified names, such as '$Package::x'
721 10         35 next if $var_name =~ m/main(?:'|::)/;
722             # Remove sigils from beginning of variable name: $ @ % {
723 10         33 $var_name =~ s/^[\$\@\%\{]+//;
724 10 100       161 # Substitute non-fully qualified vars, e.g. '$x' or '$::x', by '$main::x'
725 9         30 my $new_name = Symbol::qualify($var_name, 'main');
726 9         112 next if $new_name eq $var_name;
727             $var_name = quotemeta( $var_name );
728 9         30 $s =~ s/$var_name/$new_name/;
729             }
730             $new_val .= $s;
731 1         4 } else {
732             # A quoted section, to keep as-is
733             $new_val .= $$s;
734 9         53 }
735             }
736 383         949 return $new_val;
737             } else {
738             return $val;
739             }
740             }
741              
742              
743             sub _get_variable_names {
744             # Get an arrayref of the variables names found in the provided string.
745 9     9   25 # This function is a hack, needed only because of Text::Balanced ticket #78855:
746 9         13 # https://rt.cpan.org/Public/Bug/Display.html?id=78855
747 9     172   66 my ($str) = @_;
  172         10290  
748             my $vars = [];
749             for my $var (extract_multiple($str,[sub{extract_variable($_[0],'')}],undef,1)) {
750 13         1391 # Name must start with underscore or a letter, e.g. $t $$h{a} ${$h}{a} $h->{a} @_
751 13         59 # Skip special or invalid names, e.g. $/ $1
752 13 100       51 my $tmp = $var;
753 11         27 $tmp =~ s/(?:{|})//g;
754             next if not $tmp =~ m/^[\$\@\%]+[_a-z]/i;
755 9         91 push @$vars, $var;
756             }
757             return $vars;
758             }
759              
760 700     700   1088  
761 700         1402 sub _minimize_name {
762 700         2345 my ($name_re) = @_;
763 700         1166 $name_re =~ s{[][]}{}gxms; # remove all square brackets
764 700         1237 $name_re =~ s{\A \W+ ([\w-]*) .* \z}{$1}gxms;
765             $name_re =~ s{-}{_}gxms;
766             return $name_re;
767             }
768              
769 97     97   461  
770 97 50       354 sub _minimize_entries_of {
771             my ($arg_ref) = @_;
772 97         372 return if ref $arg_ref ne 'HASH';
773 659         1162  
774 659         1738 for my $old_key (keys %$arg_ref) {
775             my $new_key = _minimize_name($old_key);
776             $arg_ref->{$new_key} = delete $arg_ref->{$old_key};
777 97         260 }
778              
779             return 1;
780             }
781              
782              
783 62     62   193 # Do match, recursively trying to expand cuddles...
784             sub _doesnt_match {
785 62         119 my ( $matcher, $argv, $arg_specs_ref ) = @_;
786 62         169  
787 62         142 our @errors; # 'our' instead of 'my' because it is needed for the re pragma
788             local @errors = ();
789             %ARGV = ();
790              
791 62         64655 # Match arguments, populate %ARGV and @errors
792             # Note that the matcher needs the pragma: use re 'eval';
793             $argv =~ m{\A (?: \s* $matcher )* \s* \z}xms;
794 62         431  
795 12 100       61 # Report errors in passed arguments
796 5         23 for my $error (@errors) {
797 5         71 if ( $error =~ m/\A ((\W) (\w) (\w+))/xms ) {
798 5 100       33 my ( $bundle, $marker, $firstchar, $chars ) = ( $1, $2, $3, $4 );
799             $argv =~ s{\Q$bundle\E}{$marker$firstchar $marker$chars}xms;
800             return if !_doesnt_match( $matcher, $argv, $arg_specs_ref );
801 10         23 }
  10         39  
802 54         115 ARG:
803 54         74 for my $arg_spec_ref ( values %{$arg_specs_ref} ) {
804             our $bad_type;
805 54 100 100     5279 local $bad_type;
806             next ARG
807             if $error !~ m/\A [\s\0\1]* ($arg_spec_ref->{generic_matcher})/xms
808             || !$bad_type;
809 4         22
810 4         110 my $msg = _type_error( $bad_type->{arg}, $bad_type->{var},
811             $bad_type->{val}, $bad_type->{type}, $bad_type->{type_error} );
812 6         62 return $msg;
813             }
814             return "Unknown argument: $error";
815 50         462 }
816              
817             return 0; # No error
818             }
819              
820 629     629   938  
821 629         1014 sub _escape_arg {
822 629         1686 my $arg = shift;
823             my ($num_replaced) = ($arg =~ tr/ \t/\0\1/);
824             return $arg;
825             }
826              
827 428     428   695  
828 428         850 sub _rectify_arg {
829 428         1421 my $arg = shift;
830             my ($num_replaced) = ($arg =~ tr/\0\1/ \t/);
831             return $arg;
832             }
833              
834 49     49   263  
835 275         427 sub _rectify_all_args {
  275         650  
836 286 50       581 while ( my (undef, $arg_list) = each %ARGV ) {
837 286         407 for my $arg ( @{$arg_list} ) {
  286         717  
838 312 100       578 if ( ref $arg eq 'HASH' ) {
839 35         41 for my $var ( values %{$arg} ) {
  135         202  
  35         53  
840             if ( ref $var eq 'ARRAY' ) {
841 277         508 $var = [ map { _rectify_arg($_) } @{$var} ];
842             } else {
843             $var = _rectify_arg($var);
844             }
845 0 0       0 }
846 0         0 } else {
  0         0  
  0         0  
847             if ( ref $arg eq 'ARRAY' ) {
848 0         0 $arg = [ map { _rectify_arg($_) } @{$arg} ];
849             } else {
850             $arg = _rectify_arg($arg);
851             }
852             }
853 49         101 }
854             }
855             return 1;
856             }
857              
858 49     49   270  
859             sub _verify_args {
860             my ($arg_specs_ref) = @_;
861 49         110 # Check exclusive variables, variable constraints and fill in defaults...
862 49         328 # Handle mutually exclusive arguments
863 275         369 my %seen_vars;
  275         479  
864 286         371 while ( my ($arg_name, $arg_elems) = each %ARGV ) {
  598         1814  
865 312 100       945 for my $elem (@{$arg_elems}) {
866             while ( my ($var_name) = each (%{$elem}) ) {
867             $seen_vars{$var_name} = $arg_name if $var_name;
868             }
869             }
870 49         124 }
  489         1097  
871 443         583  
  785         1849  
872             while ( my ($arg_name, $arg) = each %{$arg_specs_ref} ) {
873 345         424 while ( my ($var_name, $var) = each %{$arg->{var}} ) {
  345         753  
874 11 50 66     44 # Enforce placeholders that cannot be specified with others
875             for my $excluded_var ( @{$var->{excludes}} ) {
876 3         11 if (exists $seen_vars{$var_name} &&
877 3         4 exists $seen_vars{$excluded_var}) {
878 3 100       9 my $excl_arg = $seen_vars{$excluded_var};
879 1         2 my $msg;
880             if (exists $var->{excludes_error}) {
881 2         13 $msg = $var->{excludes_error};
882             } else {
883             $msg =
884             qq{Invalid "$excl_arg" argument.\n<$excluded_var> }.
885             qq{cannot be specified with <$var_name> because }.
886 3         8 qq{argument "$arg_name" excludes <$excluded_var>};
887             }
888             _bad_arglist($msg);
889             }
890             }
891             }
892             }
893              
894 46         167 # Enforce constraints and fill in defaults...
  445         1190  
895             ARG:
896             while (my ($arg_name, $arg_specs) = each %{$arg_specs_ref} ) {
897              
898             # Skip non-existent/non-defaulting/non-optional-defaulting arguments
899             next ARG
900 404 100 100     1314 if !exists $ARGV{$arg_name}
      100        
901             && !( $arg_specs->{has_default}
902             || $arg_specs->{has_opt_default} );
903 280         378  
  280         849  
904 280         422 # Ensure all vars exist within arg...
  280         673  
905 256         427 my @vars = keys %{$arg_specs->{placeholders}};
906 256         375 for my $index ( 0 .. $#{ $ARGV{$arg_name} } ) {
  256         393  
  256         425  
907             my $entry = $ARGV{$arg_name}[$index];
908             @{$entry}{@vars} = @{$entry}{@vars};
909              
910 256         435 # Get arg specs...
911             VAR:
912 258         399 for my $var (@vars) {
913              
914             my $arg_vars = $arg_specs->{var}->{$var};
915 258 50       498  
916             # Check constraints on vars...
917 258 100 66     1211 if ( exists $ARGV{$arg_name} ) {
    50 33        
918              
919 228 100       560 if ( ref $entry eq 'HASH' && defined $entry->{$var} ) {
920             # Named vars...
921 35         61 for my $val (
922             ref $entry->{$var} eq 'ARRAY'
923             ? @{ $entry->{$var} }
924             : $entry->{$var}
925 328 100 100     2101 )
926             {
927             if ( $arg_vars->{constraint} &&
928             !$arg_vars->{constraint}->($val) ) {
929 5         29 _bad_arglist( _type_error($arg_name, $var, $val,
930             $arg_vars->{constraint_desc},
931             $arg_vars->{type_error}) );
932 223         683 }
933             }
934             next VAR;
935 0 0       0 } elsif ( ref $entry ne 'HASH' && defined $entry ) {
936             # Unnamed vars...
937 0         0 for my $val (
938             ref $entry eq 'ARRAY'
939             ? @{$entry}
940             : $entry
941 0 0 0     0 )
942             {
943             if ( $arg_vars->{constraint} &&
944             !$arg_vars->{constraint}->($val) ) {
945 0         0 _bad_arglist( _type_error( $arg_name, $var, $val,
946             $arg_vars->{constraint_desc},
947             $arg_vars->{type_error}) );
948 0 0       0 }
949             $entry->{$var} = ''
950 0         0 unless defined( $ARGV{$arg_name} );
951             }
952             next VAR;
953             }
954             }
955              
956             # Assign placeholder defaults (if necessary)...
957 30 100 100     189 next ARG
958             if !exists $arg_vars->{default}
959             && !exists $arg_vars->{opt_default};
960              
961 17 100       58 $entry->{$var} = exists $arg_vars->{opt_default} ?
962             $arg_vars->{opt_default} :
963             $arg_vars->{default};
964             }
965             }
966 262 100       373  
  262         809  
967 35         81 # Handle defaults for missing args...
968             if ( !@{ $ARGV{$arg_name} } ) {
969 36         63 for my $var (@vars) {
970             # Assign defaults (if necessary)...
971 36 100       95 my $arg_vars = $arg_specs->{var}->{$var};
972             next ARG
973             if !exists $arg_vars->{default}; # no default specified
974 31         99  
  31         80  
975 5 100       12 # Omit default if it conflicts with a specified parameter
976 3         7 for my $excl_var ( @{$arg_specs->{var}->{$var}->{excludes}} ) {
977             if (exists $seen_vars{$excl_var}) {
978             next ARG;
979             }
980 28         104 }
981              
982             $ARGV{$arg_name}[0]{$var} = $arg_vars->{default};
983             }
984 41         183 }
985             }
986             return 1;
987             }
988              
989 9     9   51  
990 9         30 sub _type_error {
991 9         35 my ($arg_name, $var_name, $var_val, $var_constraint, $var_error) = @_;
992 9 100       27 my $msg = qq{Invalid "$arg_name" argument.\n};
993 3         7 $var_name =~ s{\W+}{}gxms;
994 3         61 if ( $var_error ) {
995             $msg = $var_error;
996 6         28 $msg =~ s{(?)}{$var_val}gxms;
997             } else {
998             $msg = qq{<$var_name> must be $var_constraint but the supplied value }.
999 9         36 qq{("$var_val") is not.};
1000             }
1001             return $msg;
1002             }
1003              
1004 51     51   157  
1005             sub _convert_to_regex {
1006             my ($args_ref) = @_;
1007 51         117  
1008             # Regexp to capture the start of a new argument
1009 51         99 my $no_esc_ws = '(?!\0)'; # no escaped whitespaces
1010 51         115  
  486         1273  
1011 435         681 my @arg_variants;
  435         1041  
1012             while ( my ($arg_name, $arg_specs) = each %{$args_ref} ) {
1013             push @arg_variants, @{$arg_specs->{variants}};
1014 51         266 }
1015 51         201  
1016 51         204 my $no_match = join('|',@arg_variants);
1017             $no_match = _escape_specials($no_match);
1018 51         138 $no_match = '(?!(?:'.$no_match.')'.$no_esc_ws.')';
  486         1478  
1019 435         711  
1020             while ( my ($arg_name, $arg) = each %{$args_ref} ) {
1021             my $regex = $arg_name;
1022 435         776  
1023 435         972 # Quotemeta specials...
1024             $regex = _escape_specials($regex);
1025             $regex = "(?:$regex)";
1026 435         2271  
1027 435         1282 # Convert optionals...
  321         1231  
1028 435         786 1 while $regex =~ s/ \[ ([^]]*) \] /(?:$1)?/gxms;
1029             $regex =~ s/ (\s+) /$1.'\s*'.$no_esc_ws/egxms;
1030             my $generic = $regex;
1031              
1032 347         975 # Set the matcher
1033 347         526 $regex =~
1034 347   100     1256 s{ < (.*?) >(\.\.\.|) }
1035 347         967 { my ($var_name, $var_rep) = ($1, $2);
1036             $var_name =~ s/(\s+)\[\\s\\0\\1]\*/$1/gxms;
1037             my $type = $arg->{var}{$var_name}{type} || q{};
1038             $arg->{placeholders}->{$var_name} = undef;
1039 347 100       1518 my $matcher =
    50          
1040             $type =~ m{\A\s*/.*/\s*\z}xms
1041 347 100       1947 ? eval "qr$type"
1042             : $std_matcher_for{ $type }
1043             or _fail("Unknown type ($type) in specification: $arg_name");
1044             $var_rep ?
1045             "(?:[\\s\\0\\1]*$no_match($matcher)(?{push \@{(\$ARGV{q{$arg_name}}||=[{}])->[-1]{q{$var_name}}}, \$^N}))+"
1046 435 100       1360 :
1047 167         414 "(?:$no_match($matcher)(?{(\$ARGV{q{$arg_name}}||=[{}])->[-1]{q{$var_name}} = \$^N}))";
1048             }gexms
1049             or do {
1050 435 100       956 $regex .= "(?{(\$ARGV{q{$arg_name}}||=[{}])->[-1]{q{}} = 1})";
1051 6         19 };
1052              
1053             if ( $arg->{is_repeatable} ) {
1054             $arg->{matcher} = "$regex (?:(?
1055             } else {
1056 429 100       2120 $arg->{matcher} = "(??{exists\$ARGV{q{$arg_name}}?'(?!)':''}) "
1057             . (
1058             $arg->{false_vals}
1059             ? "(?:$arg->{false_vals} (?:(? 0 }] }) | $regex (?:(? 1}] }))"
1060             : "$regex (?:(?
1061             );
1062 435         1508 }
1063 347         784  
1064 347         485 # Set the generic matcher
1065 347   100     1107 $generic =~
1066 347   100     1173 s{ < (.*?) > }
1067             { my $var_name = $1;
1068             $var_name =~ s/(\s+)\[\\s\\0\\1]\*/$1/gxms;
1069 347 100       1165 my $type = $arg->{var}{$var_name}{type} || q{};
1070 347         1770 my $type_error = $arg->{var}{$var_name}{type_error} || q{};
1071             my $matcher = $type =~ m{\A\s*/.*/\s*\z}xms
1072             ? eval "qr$type"
1073             : $std_matcher_for{ $type };
1074 435         1238 "(?:($matcher|([^\\s\\0\\1]+)"
1075             . "(?{\$bad_type ||= "
1076 51         168 . "{arg=>q{$arg_name},type=>q{$type},type_error=>q{$type_error}, var=>q{<$var_name>},val=>\$^N};})))"
1077             }gexms;
1078             $arg->{generic_matcher} = $generic;
1079             }
1080             return 1;
1081             }
1082 486     486   765  
1083 486         972  
1084 486         1218 sub _escape_specials {
1085             # Escape quotemeta special characters
1086             my $arg = shift;
1087             $arg =~ s{([@#\$^*()+{}?])}{\\$1}gxms;
1088             return $arg;
1089 0     0   0 }
1090              
1091 0 0       0  
1092             sub _print_pod {
1093 0 0       0 my ( $pod, $paged ) = @_;
  0         0  
  0         0  
1094              
1095             if ($paged) {
1096             # Page output
1097 0 0       0 eval { require IO::Pager::Page } or eval { require IO::Page };
1098 0         0 }
1099 0         0
1100             # Convert POD to plaintext, wrapping the lines at 76 chars and print to STDOUT
1101 0         0 open my $parser_in, '<', \$pod or croak "Could not read from variable because $!";
1102             Pod::PlainText->new()->parse_from_filehandle($parser_in);
1103             close $parser_in;
1104              
1105             return 1;
1106             }
1107              
1108 488     488   925  
1109 488 100       1493 sub _validate_name {
1110 303         497 # Check that the argument name only has pairs of < > brackets (ticket 34199)
1111 303         462 # Return the name of the variables that this argument specifies
1112 303     3455   1898 my ($name) = @_;
  3455         251756  
1113 842 100       36487 if ($name =~ m/[<>]/) { # skip expensive Text::Balance functions if possible
1114 393         1720 my %var_names;
1115 393 100       1180 my $pos = 0;
1116 2         7 for my $s (extract_multiple($name,[sub{extract_bracketed($_[0],'<>')}],undef,0)) {
1117             next if not $s =~ m/[<>]/;
1118 391         600 $s =~ s/^<(.*)>$/$1/;
1119 391 100       1290 if ( $s =~ m/[<>]/ ) {
1120             _fail( 'Invalid argument specification: '.$name );
1121 301         1547 }
1122             $pos++;
1123 185         408 $var_names{$s} = $pos if not exists $var_names{$s};
1124             }
1125             return \%var_names;
1126             } else {
1127             return {};
1128             }
1129 798     798   30267 }
1130              
1131 798         2485  
1132 823         3877 sub _get_variants {
1133             my @arg_desc = shift =~ m{ [^[|]+ (?: $optional_re [^[|]* )* }gmxs;
1134              
1135             for (@arg_desc) {
1136 798 100       2527 s{^ \s+ | \s+ $}{}gxms;
1137             }
1138 761         3489  
1139             # Only consider first "word"...
1140             return $1 if $arg_desc[0] =~ m/\A (< [^>]+ >)/xms;
1141 761         1302  
1142 761         1525 $arg_desc[0] =~ s/\A ([^\s<]+) \s* (?: < .*)? \z/$1/xms;
1143 3047         4867  
1144 3047         4473 # Variants are all those with and without each optional component...
1145             my %variants;
1146 3047 100       7754 while (@arg_desc) {
1147 1164         2172 my $arg_desc_with = shift @arg_desc;
1148             my $arg_desc_without = $arg_desc_with;
1149 3047 100       7090  
1150 1164         2222 if ( $arg_desc_without =~ s/ \[ [^][]* \] //xms ) {
1151 1164         2659 push @arg_desc, $arg_desc_without;
1152 1097         1594 }
1153 1097         3050 if ( $arg_desc_with =~ m/ [[(] ([^][()]*) [])] /xms ) {
1154 1097         2523 my $option = $1;
1155             for my $alternative ( split /\|/, $option ) {
1156             my $arg_desc = $arg_desc_with;
1157             $arg_desc =~ s{[[(] [^][()]* [])]}{$alternative}xms;
1158 3047         6624 push @arg_desc, $arg_desc;
1159 3047         7667 }
1160 3047         7635 }
1161              
1162             $arg_desc_with =~ s/[][]//gxms;
1163 761         3034 $arg_desc_with =~ s/\b[^-\w] .* \z//xms;
1164             $variants{$arg_desc_with} = 1;
1165             }
1166              
1167             return keys %variants;
1168 565 50   565   2019 }
  537         1688  
1169              
1170              
1171             sub _longestname {
1172             return ( sort { length $a <=> length $b || $a cmp $b } @_ )[-1];
1173 45     45   88 }
1174 45         82  
1175 45         105  
1176 45   50     167 sub _export_var {
1177 65     65   629 my ( $prefix, $key, $value ) = @_;
  65         143  
  65         22128  
1178 45 100       88 my $export_as = $prefix . $key;
  45         257  
1179 45         128 $export_as =~ s{\W}{_}gxms; # mainly for '-'
1180             my $callpkg = caller( $export_lvl + ($Exporter::ExportLevel || 0) );
1181             no strict 'refs';
1182             *{"$callpkg\::$export_as"} = ( ref $value ) ? $value : \$value;
1183             return 1;
1184             }
1185 130     130   538  
1186              
1187 130         768 # Utility sub to factor out hash key aliasing...
1188 910         1417 sub _make_equivalent {
1189 2730         5921 my ( $hash_ref, %alias_hash ) = @_;
1190              
1191             while ( my ( $name_re, $aliases ) = each %alias_hash ) {
1192             for my $alias (@$aliases) {
1193 130         339 $hash_ref->{$alias} = $hash_ref->{$name_re};
1194             }
1195             }
1196              
1197             return 1;
1198             }
1199 12     12   34  
1200 12         2808  
1201             # Report problems in specification and die
1202             sub _fail {
1203             my (@msg) = @_;
1204             croak "Getopt::Euclid: @msg";
1205             }
1206 67     67   449  
1207              
1208             sub _get_pod_names {
1209 67 50       238 # Parse the POD of the caller program and its modules.
1210 0         0 my @caller = caller(1);
1211 0         0  
1212 0         0 # Sanity check
1213             if ($has_run) {
1214             carp 'Getopt::Euclid loaded a second time';
1215             warn "Second attempt to parse command-line was ignored\n";
1216 67 100       316 return 0;
1217 4         20 }
1218 4         10  
1219             # Handle calls from .pm files
1220 65     65   585 if ( $caller[1] =~ m/[.]pm \z/xms ) {
  65         189  
  65         48752  
1221             my @caller = caller(1); # at import()'s level
1222 4 50       5 push @pod_names, $caller[1];
  4         41  
1223 4         6 # Install this import() sub as module's import sub...
1224 4         25 no strict 'refs';
1225 4     4   70 croak '.pm file cannot define an explicit import() when using Getopt::Euclid'
  4         17  
1226 4         25 if *{"$caller[0]::import"}{CODE};
1227             my $lambda; # Needed so the anon sub is generated at run-time
1228 4         152 *{"$caller[0]::import"}
1229             = bless sub { $lambda = 1; goto &Getopt::Euclid::import },
1230             'Getopt::Euclid::Importer';
1231              
1232 63 100       1761 return 0;
1233             }
1234 63         416  
1235             # Add name of caller program
1236             push @pod_names, $0 if (-e $0); # When calling perl -e '...', $0 is '-e', i.e. not a actual file
1237              
1238             return 1;
1239 103     103   228 }
1240 103         189  
1241              
1242 103         469 sub _insert_default_values {
  880         1500  
1243 436         778 my ($args) = @_;
1244 436         697 my $pod_string = '';
1245 436         822 # Retrieve item names in sequential order
1246             for my $item_name ( sort { $args->{$a}->{'seq'} <=> $args->{$b}->{'seq'} } (keys %$args) ) {
1247 436         586 my $item_spec = $args->{$item_name}->{'src'};
  672         2016  
1248             $item_spec =~ s/=for(.*)//ms;
1249 236         388 $pod_string .= "=item $item_name\n\n";
1250 472         746 # Get list of variable for this argument
1251 472 100       864 while ( my ($var_name, $var) = each %{$args->{$item_name}->{var}} ) {
1252 132 100       467 # Get default for this variable
    50          
1253 1         2 for my $default_type ( 'default', 'opt_default' ) {
  1         13  
1254             my $var_default;
1255 131         242 if (exists $var->{$default_type}) {
1256             if (ref($var->{$default_type}) eq 'ARRAY') {
1257 0         0 $var_default = join(' ', @{$var->{$default_type}});
1258             } elsif (ref($var->{$default_type}) eq '') {
1259             $var_default = $var->{$default_type};
1260 340         484 } else {
1261             carp 'Getopt::Euclid found an unexpected default value type';
1262 472         4265 }
1263             } else {
1264             $var_default = 'none';
1265 436 100       1110 }
1266 1         4 $item_spec =~ s/$var_name\.$default_type/$var_default/g;
1267 1         6 }
1268             }
1269             if ($item_spec =~ m/(\S+(\.(?:opt_)?default))/) {
1270 435         845 my ($reference, $default_type) = ($1, $2);
1271             _fail( "Invalid reference to field $reference in argument ".
1272 102         343 "description:\n$item_spec" );
1273 102         309 }
1274             $pod_string .= $item_spec;
1275             }
1276             $pod_string = "=over\n\n".$pod_string."=back\n\n";
1277             return $pod_string;
1278             }
1279              
1280              
1281             1; # Magic true value required at end of module
1282              
1283              
1284             =head1 NAME
1285              
1286             Getopt::Euclid - Executable Uniform Command-Line Interface Descriptions
1287              
1288             =head1 VERSION
1289              
1290             This document describes Getopt::Euclid version 0.4.5
1291              
1292             =head1 SYNOPSIS
1293              
1294             use Getopt::Euclid;
1295              
1296             if ($ARGV{-i}) {
1297             print "Interactive mode...\n";
1298             }
1299              
1300             for my $x (0..$ARGV{-size}{h}-1) {
1301             for my $y (0..$ARGV{-size}{w}-1) {
1302             do_something_with($x, $y);
1303             }
1304             }
1305              
1306             __END__
1307              
1308             =head1 NAME
1309              
1310             yourprog - Your program here
1311              
1312             =head1 VERSION
1313              
1314             This documentation refers to yourprog version 1.9.4
1315              
1316             =head1 USAGE
1317              
1318             yourprog [options] -s[ize]=x -o[ut][file]
1319              
1320             =head1 REQUIRED ARGUMENTS
1321              
1322             =over
1323              
1324             =item -s[ize]=x
1325              
1326             Specify size of simulation
1327              
1328             =for Euclid:
1329             h.type: int > 0
1330             h.default: 24
1331             w.type: int >= 10
1332             w.default: 80
1333              
1334             =item -o[ut][file]
1335              
1336             Specify output file
1337              
1338             =for Euclid:
1339             file.type: writable
1340             file.default: '-'
1341              
1342             =back
1343              
1344             =head1 OPTIONS
1345              
1346             =over
1347              
1348             =item -i
1349              
1350             Specify interactive simulation
1351              
1352             =item -l[[en][gth]]
1353              
1354             Length of simulation. The default is l.default
1355              
1356             =for Euclid:
1357             l.type: int > 0
1358             l.default: 99
1359              
1360             =item --debug []
1361              
1362             Set the log level. Default is log_level.default but if you provide --debug,
1363             then it is log_level.opt_default.
1364              
1365             =for Euclid:
1366             log_level.type: int
1367             log_level.default: 0
1368             log_level.opt_default: 1
1369              
1370             =item --version
1371              
1372             =item --usage
1373              
1374             =item --help
1375              
1376             =item --man
1377              
1378             Print the usual program information
1379              
1380             =back
1381              
1382             Remainder of documentation starts here...
1383              
1384             =head1 AUTHOR
1385              
1386             Damian Conway (DCONWAY@CPAN.org)
1387              
1388             =head1 BUGS
1389              
1390             There are undoubtedly serious bugs lurking somewhere in this code.
1391             Bug reports and other feedback are most welcome.
1392              
1393             =head1 COPYRIGHT
1394              
1395             Copyright (c) 2005, Damian Conway. All Rights Reserved.
1396             This module is free software. It may be used, redistributed
1397             and/or modified under the terms of the Perl Artistic License
1398             (see http://www.perl.com/perl/misc/Artistic.html)
1399              
1400              
1401             =head1 DESCRIPTION
1402              
1403             Getopt::Euclid uses your program's own POD documentation to create a powerful
1404             command-line argument parser. This ensures that your program's documented interface
1405             and its actual interface always agree.
1406              
1407             The created command-line argument parser includes many features such as argument
1408             type checking, required arguments, exclusive arguments, optional arguments with
1409             default values, automatic usage message, ...
1410              
1411             To use the module, simply write the following at the top of your program:
1412              
1413             use Getopt::Euclid;
1414              
1415             This will cause Getopt::Euclid to be require'd and its import method will be
1416             called. It is important that the import method be allowed to run, so do not
1417             invoke Getopt::Euclid in the following manner:
1418              
1419             # Will not work
1420             use Getopt::Euclid ();
1421              
1422             When the module is loaded within a regular Perl program, it will:
1423              
1424             =over
1425              
1426             =item 1.
1427              
1428             locate any POD in the same *.pl file or its associated *.pod file.
1429              
1430             =item 2.
1431              
1432             extract information from that POD, most especially from
1433             the C<=head1 REQUIRED ARGUMENTS> and C<=head1 OPTIONS> sections,
1434              
1435             =item 3.
1436              
1437             build a parser that parses the arguments and options the POD specifies,
1438              
1439             =item 4.
1440              
1441             remove the command-line arguments from C<@ARGV> and parse them, and
1442              
1443             =item 5.
1444              
1445             put the results in the global C<%ARGV> variable (or into specifically named
1446             optional variables, if you request that -- see L).
1447              
1448             =back
1449              
1450             As a special case, if the module is loaded within some other module
1451             (i.e. from within a C<.pm> file), it still locates and extracts POD
1452             information, but instead of parsing C<@ARGV> immediately, it caches that
1453             information and installs an C subroutine in the caller module.
1454             This new C acts just like Getopt::Euclid's own import, except
1455             that it adds the POD from the caller module to the POD of the callee.
1456              
1457             All of which just means you can put some or all of your CLI specification
1458             in a module, rather than in the application's source file.
1459             See L for more details.
1460              
1461             =head1 INTERFACE
1462              
1463             =head2 Program interface
1464              
1465             You write:
1466              
1467             use Getopt::Euclid;
1468              
1469             and your command-line is parsed automagically.
1470              
1471             =head2 Module interface
1472              
1473             =over
1474              
1475             =item import()
1476              
1477             You write:
1478              
1479             use Getopt::Euclid;
1480              
1481             and your module will then act just like Getopt::Euclid (i.e. you can use
1482             your module I of Getopt::Euclid>, except that your module's POD
1483             will also be prepended to the POD of any module that loads yours. In
1484             other words, you can use Getopt::Euclid in a module to create a standard
1485             set of CLI arguments, which can then be added to any application simply
1486             by loading your module.
1487              
1488             To accomplish this trick Getopt::Euclid installs an C
1489             subroutine in your module. If your module already has an C
1490             subroutine defined, terrible things happen. So do not do that.
1491              
1492             You may also short-circuit the import method within your calling program to
1493             have the POD from several modules included for argument parsing.
1494              
1495             use Module1::Getopt (); # No argument parsing
1496             use Module2::Getopt (); # No argument parsing
1497             use Getopt::Euclid; # Arguments parsed
1498              
1499             =item process_args()
1500              
1501             Alternatively, to parse arguments from a source different from C<@ARGV>, use the
1502             C subroutine.
1503              
1504             use Getopt::Euclid qw(:defer);
1505             my @args = ( '-in', 'file.txt', '-out', 'results.txt' );
1506             Getopt::Euclid->process_args(\@args);
1507              
1508             If you want to use the :minimal or :vars mode in this type of scenario, you can
1509             pass extra options to C:
1510              
1511             use Getopt::Euclid qw(:defer);
1512             my @args = ( '-in', 'file.txt', '-out', 'results.txt' );
1513             Getopt::Euclid->process_args(\@args, {-minimal => 1, -vars => 'prefix_'});
1514              
1515             This is particularly when you plan on processing POD manually.
1516              
1517             =item process_pods()
1518              
1519             Similarly, to parse argument specifications from a source different than the
1520             current script (and its dependencies), use the C subroutine.
1521              
1522             use Getopt::Euclid ();
1523             my @pods = ( 'script.pl', 'Module.pm' );
1524             $Getopt::Euclid::MAN = Getopt::Euclid->process_pods(\@pods, {-strict => 1});
1525             my @args = ( '-in', 'file.txt', '-out', 'results.txt' );
1526             Getopt::Euclid->process_args(\@args);
1527              
1528             By default, this method will look for .pod files associated with the given .pl
1529             and .pm files and use these .pod files preferentially when available. Set
1530             -strict to 1 to only use the given files.
1531              
1532             =back
1533              
1534             =head2 POD interface
1535              
1536             This is where all the action is. POD markup can be placed in a .pod file that
1537             has the same prefix as the corresponding Perl file. Alternatively, POD can be
1538             inserted anywhere in the Perl code, but is typically added either after an
1539             __END__ statement (like in the L), or interspersed in the code: