Command Line Arguments from a File

Command Line Arguments from a File

am 14.11.2007 14:32:55 von g4173c

Greetings:

I've gotten a request to put command line arguments into a file.
This file contains other information for building parts. I thought
this would be fairly easy because I've been using Getopt::Long for a
while and thought I would just have to push the switches onto @ARGV
and call Getopt::Long a second time. The code:

elsif (/^-\w+/) {
push(@ARGV," $_");
}
&Command_Line;# Calls Getopt::Long

I noticed that I have to put a space in the " $_" or else the "-" gets
striped off. None of the options are being set this way. Any ideas
what I'm doing wrong here? Is there a better way to handle this?
Thanks in advanced for any help!

Tom

Re: Command Line Arguments from a File

am 14.11.2007 15:40:36 von Ben Morrow

Quoth T :
>
> I've gotten a request to put command line arguments into a file.

You haven't said how these arguments are stored in the file, or how you
get them out again.

> This file contains other information for building parts. I thought
> this would be fairly easy because I've been using Getopt::Long for a
> while and thought I would just have to push the switches onto @ARGV
> and call Getopt::Long a second time. The code:
>
> elsif (/^-\w+/) {

Where is the rest of this 'if'? What is $_ set to?

You are supposed to post an example we can actually run.

> push(@ARGV," $_");
> }
> &Command_Line;# Calls Getopt::Long

Don't call subs with & unless you know what it does.

> I noticed that I have to put a space in the " $_" or else the "-" gets
> striped off.

I don't believe you. What made you think that?

> None of the options are being set this way.

Well... no. Getopt::Long looks for arguments starting with '-'; an
argument starting with ' -' doesn't qualify.

> Is there a better way to handle this?

RTFM. Use Getopt::Long::GetOptionsFromString or ::GetOptionsFromArray,
which are provided for this purpose.

Ben

Re: Command Line Arguments from a File

am 14.11.2007 19:45:55 von g4173c

On Nov 14, 9:40 am, Ben Morrow wrote:
> You are supposed to post an example we can actually run.

Fair enough, I was trying to be brief, however maybe I was too brief.
Below is sample code. In the file I have:

#
# Default Command Line switches.
#
-noclearcase
-email mail

When I run the script below I get:

$ test.pl

-noclearcase -email mail
Unknown option: email mail
Died at test.pl line 10.

Looks like it's stripping off the "-" on email. If I run with command
line
options also I get:

$ test.pl -minor
-minor
No "-minor" build file?

Which isn't getting any of the command line arguments?

I know I must be doing something wrong, so any help in this is greatly
appreciated!

Thanks
Tom

Test Code Below:

#!/usr/local/bin/perl
#
#
use Getopt::Long qw(GetOptionsFromArray);
#
# Get the command line options.
#
sub Command_Line {
print "@_\n";
GetOptionsFromArray(\@_,
"major:s" => \$major,
"minor:s" => \$minor,
"qsfonly" => \$qsfonly,
"noqsf" => \$noqsf,
"noclearcase" => \$noclearcase,
"full" => \$full,
"email=s" => \$email,
"classic" => \$classic,
"version" => \$version,
"help" => \$help ) || die;
}
Command_Line(@ARGV);

#
# See if they want to use a different Control File other than the
default ALTERA file.
#
if (! @ARGV) {
$Control_File = "ALTERA";
} else {
$Control_File = "$ARGV[0]";
}
#
# Find the Altera Build file and get the variables, if not error out.
#
if ( -e "$Control_File" ) {
#
# Open Altera build file for reading and get the variables.
#
open (ALTERA, "$Control_File") || die "Can't Open File
\"$Control_File\": $!\n";
while () {
# Ingore lines that start with # or are just spaces...
if ((!/^#/) && (/\S/)){
chomp;
s/=/ /;
@x = $_;
@x = split;
if (/DESIGN/) {
$design = $x[1];
}
elsif (/REVFILE/) {
$revfilename = $x[1];
}
elsif (/MAJOR/) {
$majorrev = $x[1];
}
elsif (/MINOR/) {
$minorrev = $x[1];
}
elsif (/\.tcl$/) {
push(@qsfbld, $x[0]);
}
elsif (/^-\w+/) {
push(@CMDLINE,"$_");
}
}
}
close (ALTERA);
}
else {
print "No \"$Control_File\" build file?\n";
exit (1);
}
Command_Line(@CMDLINE);
print "@ARGV\n";
print "Major $major\n";
print "Minor $minor\n";
print "QSFOnly $qsfonly\n";
print "NoQSF $noqsf\n";
print "No Clearcase $noclearcase\n";
print "Full $full\n";
print "Email $email\n";
print "Classic $classic\n";
print "Version $version\n";
print "Help $help\n";

Re: Command Line Arguments from a File

am 14.11.2007 20:48:23 von Jim Gibson

In article <1195065955.596294.100710@22g2000hsm.googlegroups.com>,
wrote:

> On Nov 14, 9:40 am, Ben Morrow wrote:
> > You are supposed to post an example we can actually run.
>
> Fair enough, I was trying to be brief, however maybe I was too brief.
> Below is sample code. In the file I have:
>
> #
> # Default Command Line switches.
> #
> -noclearcase
> -email mail

You can append file data to the end of your program after a '__DATA__'
token and use the special file handle to read it. While this is
not something you want to do in your real program, it makes it easier
for people to help you.

See the posting guidelines for this group for ways to improve your
chances for getting useful help:



>
> When I run the script below I get:
>
> $ test.pl
>
> -noclearcase -email mail
> Unknown option: email mail
> Died at test.pl line 10.

You are passing the string "-email mail" as a single element of the
first-argument array to GetOptionsFromArray. Since this is not a valid
option, GetOptionsFromArray issues the above message (first stripping
the '-' which identifies an argument).

>
> Looks like it's stripping off the "-" on email. If I run with command
> line
> options also I get:
>
> $ test.pl -minor
> -minor
> No "-minor" build file?

While the function GetOptions will remove parsed options from the @ARGV
array, the function GetOptionsFromArray does not. Therefore, after
Command_Line has parsed @ARGV the first time, the element "-minor"
remains in $ARGV[0]. This then becomes the name of the control file
your program tests for existence. This test fails and you get the error
message as above.

Note other comments below.

> Test Code Below:
>
> #!/usr/local/bin/perl

You should have here:

use strict;
use warnings;

> #
> #
> use Getopt::Long qw(GetOptionsFromArray);
> #
> # Get the command line options.
> #
> sub Command_Line {
> print "@_\n";
> GetOptionsFromArray(\@_,
> "major:s" => \$major,
> "minor:s" => \$minor,
> "qsfonly" => \$qsfonly,
> "noqsf" => \$noqsf,
> "noclearcase" => \$noclearcase,
> "full" => \$full,
> "email=s" => \$email,
> "classic" => \$classic,
> "version" => \$version,
> "help" => \$help ) || die;
> }
> Command_Line(@ARGV);
>
> #
> # See if they want to use a different Control File other than the
> default ALTERA file.
> #
> if (! @ARGV) {
> $Control_File = "ALTERA";
> } else {
> $Control_File = "$ARGV[0]";
> }
> #
> # Find the Altera Build file and get the variables, if not error out.
> #
> if ( -e "$Control_File" ) {
> #
> # Open Altera build file for reading and get the variables.
> #
> open (ALTERA, "$Control_File") || die "Can't Open File
> \"$Control_File\": $!\n";
> while () {
> # Ingore lines that start with # or are just spaces...
> if ((!/^#/) && (/\S/)){
> chomp;
> s/=/ /;
> @x = $_;

The above line is totally unnecessary.

> @x = split;
> if (/DESIGN/) {
> $design = $x[1];
> }
> elsif (/REVFILE/) {
> $revfilename = $x[1];
> }
> elsif (/MAJOR/) {
> $majorrev = $x[1];
> }
> elsif (/MINOR/) {
> $minorrev = $x[1];
> }
> elsif (/\.tcl$/) {
> push(@qsfbld, $x[0]);
> }
> elsif (/^-\w+/) {
> push(@CMDLINE,"$_");

The above line should be:
push(@CMDLINE,@x);
> }
> }
> }
> close (ALTERA);
> }
> else {
> print "No \"$Control_File\" build file?\n";
> exit (1);
> }
> Command_Line(@CMDLINE);
> print "@ARGV\n";
> print "Major $major\n";
> print "Minor $minor\n";
> print "QSFOnly $qsfonly\n";
> print "NoQSF $noqsf\n";
> print "No Clearcase $noclearcase\n";
> print "Full $full\n";
> print "Email $email\n";
> print "Classic $classic\n";
> print "Version $version\n";
> print "Help $help\n";

--
Jim Gibson

Posted Via Usenet.com Premium Usenet Newsgroup Services
----------------------------------------------------------
** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
----------------------------------------------------------
http://www.usenet.com

Re: Command Line Arguments from a File

am 15.11.2007 01:13:36 von Ben Morrow

Quoth Jim Gibson :
> In article <1195065955.596294.100710@22g2000hsm.googlegroups.com>,
> wrote:
> >
> > When I run the script below I get:
> >
> > $ test.pl
> >
> > -noclearcase -email mail
> > Unknown option: email mail
> > Died at test.pl line 10.
>
> You are passing the string "-email mail" as a single element of the
> first-argument array to GetOptionsFromArray. Since this is not a valid
> option, GetOptionsFromArray issues the above message (first stripping
> the '-' which identifies an argument).

Note that you can use GetOptionsFromString, which is for exactly this
purpose. It uses Text::Shellwords (or rather, Text::ParseWords), which
supports shell-style quoting, so would correctly understand lines like

-email "Foo Bar "

as a user would probably expect. Since this will handle all the
splitting for you, you can do something more like

use File::Slurp qw/read_file/;

my $config = read_file $Control_File;

# note that . doesn't match newline without /s
$config =~ s/#.*//g;

GetOptionsFromString $config, ...;

and get comments and quoting handled as the shell would.

Ben