in reply to Cleansing and stacking arguments before calling system()
This is far from complete, but as the output at the bottom shows, the basic logic is inplace and functional. The regexen will require scrutiny as will the treatment of missing required values and other error handling.
I've written a simplistic parser for the purposes of testing. You my want to reject this in favour of something better.
Hope it at least demonstrates an approach to the problem.
#! 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 equ +ivalents 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+)/--maxdept +h=$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+)/--compres +sion=$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 = <DATA>; my $pInput = parseInput( \@rawInput ); # builds and returns ref to has +h 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 suppli +ed a value print LOG $pInput->{$option}, '" '; if ( $pInput->{$option} =~ $options{$option}{mask} ) { #pa +sses the mask print LOG ' passed '; if ( $options{$option}{type} eq 'boolean' ) { # try and extract a true switch my $arg = $options{$option}{maptrue}( $pInput->{$o +ption} ); # extract a false switch if that failed $arg = $options{$option}{mapfalse}( $pInput->{$opt +ion} ) if ( $arg eq $pInput->{$option} ); print LOG $/, 'using switch "', $arg, '"', $/; push @exeArgs, $arg; } else { # type = string or numeric my $arg = $options{$option}{map}( $pInput->{$optio +n} ); print LOG $/, 'using switch "', $arg, '"', $/; push @exeArgs, $arg; } } else { # Handle supplied value invalid print LOG 'failed '; if ( $options{$option}{required} ) { # they must suppl +y 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 cann +ot parse. for ( @{$pRawInput} ) { chomp; # print "'$_'\n"; my $keyseen = ''; if ( m/^\s*?(\S+)\s*?=\s*?(\S{1}.*?)$/ ) { # k +ey = 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 i +t 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 l +ine). push @{$input{extraneous}}, $_ if ! m/^$/; # discard blank +s 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
The following is a run on the limited test data supplied.
C:\test>perl 197724.pl found key: 'url' value: 'http://www.wired.com/news_drop/palmpilot/' found key: 'AvantGo' value: 'No' found key: 'maxdepth' value: '2' found key: 'bpp' value: '4' found key: 'compression' value: 'zlib' found key: 'title' value: 'Wired News' found key: 'no_url_info' value: 'True' found key: 'beamable' value: 'False' parsing completed Option maxdepth found: "2" passed using switch "--maxdepth=2" Option url found: "http://www.wired.com/news_drop/palmpilot/" passed using switch "--url="http://www.wired.com/news_drop/palmpilot/"" Option beamable found: "False" passed using switch "--not-beamable" Option title found: "Wired News" passed using switch "--title="Wired News"" Option bbpRequired option bbp missing - using default "--bbp=4" Option no_url_info found: "True" passed using switch "--no_url_info" Option AvantGo found: "No" passed using switch "--no_avantgo" Option compression found: "zlib" passed using switch "--compression=zlib" Issuing command with arguements: --maxdepth=2 --url="http://www.wired.com/news_drop/palmpilot/" --not-beamable --title="Wired News" --bbp=4 --no_url_info --no_avantgo --compression=zlib The system cannot execute the specified program. command returned: 256 C:\test>
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Cleansing and stacking arguments before calling system()
by Aristotle (Chancellor) on Sep 14, 2002 at 05:52 UTC | |
by BrowserUk (Patriarch) on Sep 14, 2002 at 06:17 UTC | |
by Aristotle (Chancellor) on Sep 14, 2002 at 06:43 UTC | |
by BrowserUk (Patriarch) on Sep 25, 2002 at 03:45 UTC | |
by hacker (Priest) on Sep 14, 2002 at 13:30 UTC | |
by hacker (Priest) on Sep 14, 2002 at 15:10 UTC | |
by Aristotle (Chancellor) on Sep 14, 2002 at 15:33 UTC |