#! perl -sw use strict; my %options = ( url => { required => 1, type => 'string', mask => qr/^(\S{1}.*?\S{1})$/io, map => sub { (my $arg = $_[0]) =~ s/(.*)/--url="$1"/io; return $arg; }, default => undef, }, title => { required => 0, type => 'string', mask => qr/^(\S{1}.*?\S{1})$/io, map => sub { (my $arg = $_[0]) =~ s/(.*)/--title="$1"/io; return $arg; }, default => undef, }, AvantGo => { required => 0, type => 'boolean', mask => qr/^(0|1|y|n|yes|no|t|f|true|false)$/io, # NOTE: Longer option MUST come before shorter equivalents in substitutions. maptrue => sub { (my $arg = $_[0]) =~ s/(1|y|yes|true|t)/--avantgo/io; return $arg; }, mapfalse => sub { (my $arg = $_[0]) =~ s/(0|no|n|false|f)/--no_avantgo/io; return $arg; }, default => '--no_avantgo', }, maxdepth => { required => 1, type => 'numeric', mask => qr/^(\d+)$/, map => sub { (my $arg = $_[0]) =~ s/(\d+)/--maxdepth=$1/o; return $arg; }, default => '--maxdepth=2', }, bbp => { required => 0, type => 'numeric', mask => qr/^(1|2|4|8|32)$/, map => sub { (my $arg = $_[0]) =~ s/(\d+)/--bbp=$1/o; return $arg; }, default => '--bbp=4', }, compression => { required => 1, type => 'numeric', mask => qr/^(zlib|zip|gzip|tar)$/i, map => sub { (my $arg = $_[0]) =~ s/(\w+)/--compression=$1/io; return $arg; }, default => '--compression=zlib', }, no_url_info => { required => 0, type => 'boolean', mask => qr/^(0|1|y|n|yes|no|t|f|true|false)$/i, maptrue => sub { (my $arg = $_[0]) =~ s/(1|yes|y|true|t)/--no_url_info/io; return $arg; }, mapfalse => sub { (my $arg = $_[0]) =~ s/(0|no|n|false|f)//io; return $arg; }, default => '', }, beamable => { required => 0, type => 'boolean', mask => qr/^(0|1|y|n|yes|no|t|f|true|false)$/i, maptrue => sub { (my $arg = $_[0]) =~ s/(1|yes|y|true|t)/--beamable/io; return $arg }, mapfalse => sub { (my $arg = $_[0]) =~ s/(0|no|n|false|f)/--not-beamable/io; return $arg; }, default => '--beamable', }, ); my @rawInput = ; my $pInput = parseInput( \@rawInput ); # builds and returns ref to hash of input parameters my @exeArgs = (); my $fatalError = 0; *LOG = *STDERR; foreach my $option (keys %options) { print LOG 'Option ', $option; if( exists $pInput->{$option} ) { # the option was present print LOG ' found: "'; if (defined $pInput->{$option}) { # and they supplied a value print LOG $pInput->{$option}, '" '; if ( $pInput->{$option} =~ $options{$option}{mask} ) { #passes the mask print LOG ' passed '; if ( $options{$option}{type} eq 'boolean' ) { # try and extract a true switch my $arg = $options{$option}{maptrue}( $pInput->{$option} ); # extract a false switch if that failed $arg = $options{$option}{mapfalse}( $pInput->{$option} ) if ( $arg eq $pInput->{$option} ); print LOG $/, 'using switch "', $arg, '"', $/; push @exeArgs, $arg; } else { # type = string or numeric my $arg = $options{$option}{map}( $pInput->{$option} ); print LOG $/, 'using switch "', $arg, '"', $/; push @exeArgs, $arg; } } else { # Handle supplied value invalid print LOG 'failed '; if ( $options{$option}{required} ) { # they must supply a valid value print LOG 'request rejected', $/; warn "bad args\n"; $fatalError = 1; next; } else { my $arg = $options{$option}{default}; print LOG 'using default "', $arg, '"', $/; push @exeArgs, $arg; } } } else { # Handle defined key without value print LOG 'no value supplied '; if ( $options{$option}{required} ) { print 'required value not supplied, request rejected', $/; warn "bad args\n"; $fatalError = 1; next; } else { my $arg = $options{$option}{default}; print 'using default "', $arg, '"', $/; push @exeArgs, $arg; } } } else { print LOG 'Required option ', $option, ' missing '; if ( $options{$option}{required} ) { # Handle missing required option print LOG '- rejecting request', $/; } else { my $arg = $options{$option}{default}; print LOG '- using default "', $arg, '"', $/; push @exeArgs, $arg; } } } if ( $fatalError ) { print LOG 'command not issued', $/; # do something about it. } else { # better handling here. print 'Issuing command with arguements:'.$/; print $_.$/ for @exeArgs; print LOG 'command returned: ', system( 'command', @exeArgs ); } exit; sub parseInput{ # Expecting a single parm die 'parseInput: Invalid parm(s) supplied'.$/ if @_ != 1 or ref($_[0]) ne 'ARRAY'; my ( $pRawInput ) = shift; my %input; $input{extraneous} = (); # set up an empty array for lines we cannot parse. for ( @{$pRawInput} ) { chomp; # print "'$_'\n"; my $keyseen = ''; if ( m/^\s*?(\S+)\s*?=\s*?(\S{1}.*?)$/ ) { # key = somestuff \n $keyseen = $1; $input{$1} = $2 if $2; # a (possibly partial) value found print "found key: '$1' value: '$2'\n"; } elsif ( m/^\s*?(\S+)\s*?=$/ ) { # key = \n WARNING This regex not exercised!!!! $keyseen = $1; $input{$1} = ''; # no value yet print "no value for key: '$keyseen' yet\n"; } elsif ($keyseen) { # $input{$keyseen} .= $_; # assume it part of the previous keys value print "Adding '$_' to the value of key: '$keyseen'\n"; } else { # line contains no key, and no key yet seen (or blank line). push @{$input{extraneous}}, $_ if ! m/^$/; # discard blanks print "Added '$_' to extraneuos array\n"; } } print "\nparsing completed \n\n"; return \%input; } __DATA__ url = http://www.wired.com/news_drop/palmpilot/ AvantGo = No maxdepth = 2 bpp = 4 compression = zlib title = Wired News no_url_info = True beamable = False