Getopt-Long-Spec
view release on metacpan or search on metacpan
lib/Getopt/Long/Spec/Parser.pm view on Meta::CPAN
use strict;
use warnings;
package Getopt::Long::Spec::Parser;
{
$Getopt::Long::Spec::Parser::VERSION = '0.002';
}
# ABSTRACT: Parse a Getopt::Long option spec into a set of attributes
use Carp;
use Data::Dumper;
# holds the current opt spec, used for error and debugging code...
my $CUR_OPT_SPEC;
# holds the parameters for the current parse
my $CUR_OPTS;
sub new {
my ( $class, %params ) = @_;
my $self = bless {%params}, $class;
return $self;
}
sub parse {
my ( $self, $spec, $params ) = @_;
# temporary globals...
$CUR_OPT_SPEC = $spec;
$CUR_OPTS = { %{ $params || {} }, %{ ref( $self ) ? $self : {} } };
print "DEBUG: spec: [$spec]\n" if $CUR_OPTS->{debug};
print "DEBUG: params: " . Dumper $CUR_OPTS if $CUR_OPTS->{debug};
croak "Invalid option specification: [$spec]"
if $spec !~ /^ ([|a-zA-Z_-]+) ([=:!+]?) (.*) /x;
my $name_spec = $1;
my $opt_type = $2 ? $2 : '';
my $arg_spec = $3 ? $3 : '';
my %name_params = $self->_process_name_spec( $name_spec );
my %arg_params = $self->_process_arg_spec( $opt_type, $arg_spec );
### It is necessary to compute these here for compat. with GoL
### I feel that this block should be relocated... but WHERE?
if ( $arg_params{negatable} ) {
my @neg_names = $self->_generate_negation_names(
$name_params{long},
$name_params{short},
@{ $name_params{aliases} },
);
push @{ $name_params{negations} }, @neg_names;
}
undef $CUR_OPT_SPEC; # done with global var.
undef $CUR_OPTS; # ditto
my %result = ( %name_params, %arg_params );
return wantarray ? %result : \%result;
}
our $NAME_SPEC_QR = qr{
( [a-zA-Z_-]+ ) # option name as $1
(
(?: [|] [a-zA-Z?_-]+ )* # aliases as $2 (split on |)
)
}x;
sub _process_name_spec {
my ( $self, $spec ) = @_;
croak "Could not parse the name part of the option spec [$CUR_OPT_SPEC]."
if $spec !~ $NAME_SPEC_QR;
my %params;
$params{long} = $1;
$params{aliases} = [
grep { defined $_ }
map {
( length( $_ ) == 1 and !$params{short} )
? ( $params{short} = $_ and undef )
: $_
}
grep { $_ }
split( '[|]', $2 )
];
return %params;
}
our $ARG_SPEC_QR = qr{
(?:
( [siof] ) # value_type as $1
| ( \d+ ) # default_num as $2 (not always valid)
| ( [+] ) # increment type as $3 (not always valid)
)
( [@%] )? # destination data type as $4
(?:
[{]
(\d+)? # min_vals as $5
(?:
[,]
(\d*)? # max_vals as $6
( run in 0.528 second using v1.01-cache-2.11-cpan-71847e10f99 )