Invalid Argument while Opening file

Discussion in 'Perl Misc' started by Pradeep, Dec 5, 2008.

  1. Pradeep

    Pradeep Guest

    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 shit 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 shit
    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;
     
    Pradeep, Dec 5, 2008
    #1
    1. Advertising

  2. 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 shit 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
     
    John W. Krahn, Dec 5, 2008
    #2
    1. Advertising

  3. Pradeep <> 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/"
     
    Tad J McClellan, Dec 5, 2008
    #3
  4. Pradeep <> 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/"
     
    Tad J McClellan, Dec 5, 2008
    #4
  5. Pradeep

    smallpond Guest

    On Dec 5, 6:23 am, Pradeep <> 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?
     
    smallpond, Dec 5, 2008
    #5
  6. >>>>> "Pradeep" == Pradeep <> 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
    <> <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
     
    Randal L. Schwartz, Dec 5, 2008
    #6
  7. Pradeep

    Guest

    Pradeep <> 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.
     
    , Dec 5, 2008
    #7
  8. Pradeep

    smallpond Guest

    On Dec 5, 6:23 am, Pradeep <> 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
     
    smallpond, Dec 5, 2008
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Java Guy
    Replies:
    1
    Views:
    714
    Manish Pandit
    Oct 15, 2006
  2. Adi
    Replies:
    1
    Views:
    522
    Steve C. Orr [MCSD, MVP, CSM, ASP Insider]
    Jul 25, 2007
  3. Gabriel Genellina

    Re: file write IOError Invalid argument

    Gabriel Genellina, Jul 20, 2009, in forum: Python
    Replies:
    0
    Views:
    460
    Gabriel Genellina
    Jul 20, 2009
  4. Matt Scilipoti
    Replies:
    2
    Views:
    218
    Matt Scilipoti
    Jun 6, 2007
  5. Java Guy
    Replies:
    1
    Views:
    336
Loading...

Share This Page