P
Pradeep
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;
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;