Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Invalid Argument while Opening file

Reply
Thread Tools

Invalid Argument while Opening file

 
 
Pradeep
Guest
Posts: n/a
 
      12-05-2008
Hi all,
When I was writing a code which will check some syntax of the files
inside a directory. The first_pass proc gathers all the related
variables and second_pass proc process those lines inside the file.
When I ran the program it gave an error:
Couldn't open input file "a.tcl": Invalid argument at C:/qtcheckref/
checktclvars.pl line 268, <INFILE> line 13591.

Could anyone help me in this regard?


$ignoreArrays = " $ignoreArrays";
$varNames = " argv $ignoreVars";

@files = ();

# Do the actual work
#
while ($file = shift())
{
push @files,$file;
}

#
# Run the first pass - collect variable names
#
@temp = @files;
while ($file = shift(@temp))
{
$varNames = first_pass($file,$varNames);
}

#
# Run the second pass - check variable names
#
@temp = @files;
while ($file = shift(@temp))
{
while (<$file>)
{
print "Checking $_\n";
second_pass( $_ , $varNames );
}
}

#--------------------------------------------------------------------------

#
# Add_Var:
# Add to the list of known variables
#
# parameters:
# $_[0] - variable to add
# $_[1] - list of known variables so far
#
# returns:
# The new list of known variables
#
sub add_var {
my $var = $_[0];
my $vars = $_[1];

$pattern = $var;
$pattern =~ s/\)/\\\)/;
$pattern =~ s/\(/\\\(/;

if ($vars !~ / $pattern/)
{
$vars = "$vars $var";
}

return $vars;
}

#
# First pass:
# Pass over the file, and collect variable definitions.
# Note: We ignore variable names with '$'s in them,
# or variable names with [set xxx] in them.
#
# When arrays are found, collect the name of the array.
# Also collect the element of the array
# if the array index has no weird **** in it.
#
# parameters:
# $_[0] - filename
# $_[1] - list of known variables so far
#
sub first_pass {
my $infile = $_[0];
my $vars = $_[1];
my $array, $var, $temp, $key;

open(INFILE,"<$infile")
|| die "Couldn't open input file '$infile': $!";

while (<INFILE>)
{
$line = $_;

# strip comments
$line =~ s/^\s*(\#.*)//;
$line =~ s/;(\#.*)//;

# Check for continuing line ('\' at end)
while ( $line =~ /\\\s*$/ )
{
# strip the tailing '\' and newline
$line =~ s/\\.*$//s;
$nextLine = <INFILE>;

$line = "$line $nextLine";

# Now re-strip comments
$line =~ s/^\s*(\#.*)//;
$line =~ s/;(\#.*)//;
}


# Look for statements of the form "set a b" (or "set
namespace::a b")
while ( $line =~ /set\s+(\w*:?(\w+)/g )
{
$vars = add_var($2, $vars);
# if this is an array element, we've already got the name
of the array.
# see if we can get the element of the array also.
if ( $line =~ /set\s+(\w+\(\w+\))/ )
{
$vars = add_var($1, $vars);
}
}

# Look for statements of the form "foreach a ..."
if ($line =~ s/foreach\s+//)
{
# match "foreach a $b" and "foreach a $b c $d"
while ($line =~ /\{?(\w+)\}?\s+\S+/g)
{
$vars = add_var($1, $vars);
}
}

# Look for statements of the form "gets channelId varName"
if ($line =~ s/gets\s+\S+\s+(\w+)//)
{
$vars = add_var($1, $vars);
}

# Look for statements of the form "lappend varName values"
if ($line =~ s/lappend\s+(\w+)//)
{
$vars = add_var($1, $vars);
}

# Look for statements of the form "global a"
if ($line =~ /global\s+(\w+)/)
{
$vars = add_var($1, $vars);
}

# Look for statements of the form "catch { ... } var"
if ($line =~ /catch\s+(\{[^\}]+\}|\"[^\"]+\")\s+(\w+)/)
{
$vars = add_var($2, $vars);
}

# Look for statements of the form "proc .... { varname1
varname2 } {"
if ( $line =~ /^proc/ ) {
$line =~ s/^proc [^\{]+\{\s*//;

while ($line =~ /((\w|_)+)\W+/g)
{
$vars = add_var($1, $vars);
}
}

# Look for statements of the form "array set arrayName[list ...
if ( $line =~ /\s*array\s+set\s+(\w+)\s+\[\s*list/ )
{
$array = $1;
$temp = $line;

# strip off the crap at the front
$temp =~ s/\s*array\s+set\s+\w+\s+\[\s*list\s*//;

# look for elements being defined (ie. 'key value' pairs)
while ( $temp =~ /((\[[^\]]\]|\S+)+)\s+(\{[^\}]+\}|\"[^\"]+
\"|\[[^\]]+\]|\S+)+/g )
{
$key = $1;

# only add it if there's no weird ****
if ($key =~ /\w+/)
{
$var = "$array($key)";
$vars = add_var($var, $vars);
}
}
}
}
return $vars;

close(INFILE);
}

#
# Second pass:
# Pass over the file, looking for:
# - undefined variables
# - 'set $varname value' style errors
# - 'foreach $varname list' style errors
#
# parameters:
# $_[0] - filename
# $_[1] - the list of known variables
#
# returns:
# nothing
#
sub second_pass {
my $infile = $_[0];
my $vars = $_[1];
my $lineNum = 0;
my $array, $var, $pattern, $suggest;

open(INFILE,"<$infile")
|| die "Couldn't open input file $infile: $!";

while (<INFILE>)
{
$line = $_;
$lineNum++;

# strip comments
$line =~ s/^\s*\#.*//;
$line =~ s/;\#.*//;

# Check for continuing line ('\' at end)
while ( $line =~ /\\\s*$/ )
{
$lineNum++;

# strip the tailing '\' and newline
$line =~ s/\\.*$//s;
 
Reply With Quote
 
 
 
 
John W. Krahn
Guest
Posts: n/a
 
      12-05-2008
Pradeep wrote:
>
> When I was writing a code which will check some syntax of the files
> inside a directory. The first_pass proc gathers all the related
> variables and second_pass proc process those lines inside the file.
> When I ran the program it gave an error:
> Couldn't open input file "a.tcl": Invalid argument at C:/qtcheckref/
> checktclvars.pl line 268, <INFILE> line 13591.
>
> Could anyone help me in this regard?
>
>
> $ignoreArrays = " $ignoreArrays";
> $varNames = " argv $ignoreVars";
>
> @files = ();
>
> # Do the actual work
> #
> while ($file = shift())
> {
> push @files,$file;
> }


Or simply:

my @files = @ARGV;


> #
> # Run the first pass - collect variable names
> #
> @temp = @files;
> while ($file = shift(@temp))
> {
> $varNames = first_pass($file,$varNames);
> }


If you have a file named "0" your loop will end.

foreach my $file ( @files ) {
$varNames = first_pass( $file, $varNames );
}


> #
> # Run the second pass - check variable names
> #
> @temp = @files;
> while ($file = shift(@temp))
> {
> while (<$file>)


You are trying to read lines from the filehandle $file but $file
contains the *name* of a file, not a filehandle.


> {
> print "Checking $_\n";
> second_pass( $_ , $varNames );
> }
> }


foreach my $file ( @files ) {
print "Checking $file\n";
second_pass( $file, $varNames );
}


> #--------------------------------------------------------------------------
>
> #
> # Add_Var:
> # Add to the list of known variables
> #
> # parameters:
> # $_[0] - variable to add
> # $_[1] - list of known variables so far
> #
> # returns:
> # The new list of known variables
> #
> sub add_var {
> my $var = $_[0];
> my $vars = $_[1];
>
> $pattern = $var;
> $pattern =~ s/\)/\\\)/;
> $pattern =~ s/\(/\\\(/;
>
> if ($vars !~ / $pattern/)
> {
> $vars = "$vars $var";
> }
>
> return $vars;
> }


Or simply:

sub add_var {
my ( $var, $vars ) = @_;

if ($vars !~ / \Q$var/)
{
$vars .= " $var";
}

return $vars;
}


> #
> # First pass:
> # Pass over the file, and collect variable definitions.
> # Note: We ignore variable names with '$'s in them,
> # or variable names with [set xxx] in them.
> #
> # When arrays are found, collect the name of the array.
> # Also collect the element of the array
> # if the array index has no weird **** in it.
> #
> # parameters:
> # $_[0] - filename
> # $_[1] - list of known variables so far
> #
> sub first_pass {
> my $infile = $_[0];
> my $vars = $_[1];
> my $array, $var, $temp, $key;
>
> open(INFILE,"<$infile")
> || die "Couldn't open input file '$infile': $!";
>
> while (<INFILE>)
> {
> $line = $_;
>
> # strip comments
> $line =~ s/^\s*(\#.*)//;
> $line =~ s/;(\#.*)//;
>
> # Check for continuing line ('\' at end)
> while ( $line =~ /\\\s*$/ )
> {
> # strip the tailing '\' and newline
> $line =~ s/\\.*$//s;
> $nextLine = <INFILE>;
>
> $line = "$line $nextLine";
>
> # Now re-strip comments
> $line =~ s/^\s*(\#.*)//;
> $line =~ s/;(\#.*)//;
> }


while (my $line = <INFILE>)
{
# strip comments
$line =~ s/^\s*(#.*)//;
$line =~ s/;(#.*)//;

# Check for continuing line ('\' at end)
if ( $line =~ s/\\\s*\n\z// )
{
$line .= ' ' . <INFILE>;

# Now re-strip comments
redo;
}



John
--
Those people who think they know everything are a great
annoyance to those of us who do. -- Isaac Asimov
 
Reply With Quote
 
 
 
 
Tad J McClellan
Guest
Posts: n/a
 
      12-05-2008
Pradeep <(E-Mail Removed)> wrote:

> Couldn't open input file "a.tcl": Invalid argument at C:/qtcheckref/

^ ^
> checktclvars.pl line 268, <INFILE> line 13591.


> open(INFILE,"<$infile")
> || die "Couldn't open input file '$infile': $!";

^ ^

It appears that you have a corrupted install of perl itself, as it is
somehow converting single quotes into double quotes...

Is the code above "line 268"?

....


> open(INFILE,"<$infile")
> || die "Couldn't open input file $infile: $!";



.... or is this "line 268"?


Now it appears that the corruption is *inserting* double quote characters...


--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
 
Reply With Quote
 
Tad J McClellan
Guest
Posts: n/a
 
      12-05-2008
Pradeep <(E-Mail Removed)> wrote:

> @files = ();
>
> # Do the actual work
> #
> while ($file = shift())
> {
> push @files,$file;
> }



@files = @ARGV; # replace all of the above with a single copy


Note that @files contains filenames (strings).


> while ($file = shift(@temp))
> {
> $varNames = first_pass($file,$varNames);
> }



Are you familiar with the "foreach" control structure?

You should be...

See the "Foreach Loops" in perlsyn.pod


> @temp = @files;



Note that @temp also contains filenames (strings).


> while ($file = shift(@temp))



Note that $file also contains a filename (string).


> {
> while (<$file>)



You should always enable warnings when developing Perl code!

The input operator takes a filehandle not a filename.


> sub add_var {
> my $var = $_[0];
> my $vars = $_[1];



my( $var, $vars ) = @_; # a better way of copying arguments


> $pattern =~ s/\)/\\\)/;



The 2nd (replacement) part of s/// is not a regular expression, it
is a double quotish string.

Parenthesis are not meta in double quoted strings, so you have
more backslashes than you need:

$pattern =~ s/\)/\\)/;


> while (<INFILE>)
> {
> $line = $_;



If you want the input line in $line, then why put it somewhere else then
copy it rather than simply put it where you want it when you first get it?


while ( my $line = <INFILE> )


> $line =~ s/^\s*(\#.*)//;



Number signs are not meta in regular expressions. You have more
backslashes than you need.

You should not capture if you are not going to use the string
that is captured...


$line =~ s/^\s*#.*//;


> while ( $line =~ /\\\s*$/ )
> {
> # strip the tailing '\' and newline
> $line =~ s/\\.*$//s;



Note that this pattern is not the same as the pattern in the while()...

It will change

I have a backslash in the \middle and at the end too\

into

I have a backslash in the

You can use s/// in the while condition you know:

while ( $line =~ s/\\\s*$// )


> $line = "$line $nextLine";



Same as

$line .= " $nextLine";


> while ($line =~ /((\w|_)+)\W+/g)



Same as

while ($line =~ /(\w+)\W+/g)

since \w already contains underscore.


--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
 
Reply With Quote
 
smallpond
Guest
Posts: n/a
 
      12-05-2008
On Dec 5, 6:23 am, Pradeep <(E-Mail Removed)> wrote:
> Hi all,
> When I was writing a code which will check some syntax of the files
> inside a directory. The first_pass proc gathers all the related
> variables and second_pass proc process those lines inside the file.
> When I ran the program it gave an error:
> Couldn't open input file "a.tcl": Invalid argument at C:/qtcheckref/
> checktclvars.pl line 268, <INFILE> line 13591.
>
> Could anyone help me in this regard?



> return $vars;
>
> close(INFILE);
>


How do you get to the close statement?
 
Reply With Quote
 
Randal L. Schwartz
Guest
Posts: n/a
 
      12-05-2008
>>>>> "Pradeep" == Pradeep <(E-Mail Removed)> writes:

Pradeep> my $array, $var, $temp, $key;

use strict and/or use warnings would have both caught this error.

Clearly, you're not using either, despite all the tutorials that
say to do so.

Why don't you start there, and when you fix everything they point out,
come back here?

print "Just another Perl hacker,"; # the original

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<(E-Mail Removed)> <URL:http://www.stonehenge.com/merlyn/>
Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc.
See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion
 
Reply With Quote
 
xhoster@gmail.com
Guest
Posts: n/a
 
      12-05-2008
Pradeep <(E-Mail Removed)> wrote:
> Hi all,
> When I was writing a code which will check some syntax of the files
> inside a directory. The first_pass proc gathers all the related
> variables and second_pass proc process those lines inside the file.
> When I ran the program it gave an error:
> Couldn't open input file "a.tcl": Invalid argument at C:/qtcheckref/
> checktclvars.pl line 268, <INFILE> line 13591.
>
> Could anyone help me in this regard?


If you are going to post 235 lines of code (and not even have that code
be complete at 268 lines), which you really shouldn't do, then you should
at least tell us which of those lines corresponds to line 268 of your
original code.

> open(INFILE,"<$infile")
> || die "Couldn't open input file '$infile': $!";


If you accurately reported the error message, then the absence of literal
single quotes suggests that this is not line 268.

....

> open(INFILE,"<$infile")
> || die "Couldn't open input file $infile: $!";


If you accurately reported the error message, and if this is line 268,
then the value of the variable $infile seems to contain literal double
quotes in it, as if the name of the file included quote symbols. On
windows, this apparently is not allowed.


Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
 
Reply With Quote
 
smallpond
Guest
Posts: n/a
 
      12-05-2008
On Dec 5, 6:23 am, Pradeep <(E-Mail Removed)> wrote:
> Hi all,
> When I was writing a code which will check some syntax of the files
> inside a directory. The first_pass proc gathers all the related
> variables and second_pass proc process those lines inside the file.
> When I ran the program it gave an error:
> Couldn't open input file "a.tcl":

^^^^^

Now I realize what your program is for. You are using perl
to check syntax of tcl files. That's like using a Ferrari to
tow your Corvair. Just convert all your code to perl and you
won't have to do this code at all.

To check the syntax of perl code:

perl -c myperlcode
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: file write IOError Invalid argument Gabriel Genellina Python 0 07-20-2009 05:54 AM
File.utime returns Invalid argument on Windows (winXP, ruby 1.8.5/1.8.6). Matt Scilipoti Ruby 2 06-06-2007 02:58 PM
How do fix: "Wrong number of arguments" / "invalid propert assignment"/ "Invalid argument" Java Guy Javascript 1 10-15-2006 08:41 PM
How do fix: "Wrong number of arguments" / "invalid propert assignment"/ "Invalid argument" Java Guy Java 1 10-15-2006 08:31 PM
Word file not opening from Adm -My recent docs but opening from file menu of Word Thaqalain Computer Support 0 06-30-2005 02:20 AM



Advertisments